From c976839a632c61917bcc81dbaea8ec32cf5249e8 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 10:50:00 +1100 Subject: [PATCH 01/20] refactor prompt handling in integration tests --- .../components/confirmation_asserter.go | 52 +++++++++++++++++++ pkg/integration/components/input.go | 12 +---- pkg/integration/tests/branch/delete.go | 5 +- pkg/integration/tests/branch/rebase.go | 15 ++++-- .../tests/branch/rebase_and_drop.go | 15 ++++-- .../cherry_pick/cherry_pick_conflicts.go | 10 +++- pkg/integration/tests/commit/revert.go | 5 +- .../tests/custom_commands/form_prompts.go | 5 +- .../tests/custom_commands/multiple_prompts.go | 5 +- pkg/integration/tests/file/discard_changes.go | 5 +- .../tests/interactive_rebase/amend_merge.go | 5 +- pkg/integration/tests/misc/confirm_on_quit.go | 5 +- 12 files changed, 114 insertions(+), 25 deletions(-) create mode 100644 pkg/integration/components/confirmation_asserter.go diff --git a/pkg/integration/components/confirmation_asserter.go b/pkg/integration/components/confirmation_asserter.go new file mode 100644 index 000000000..fa11e814f --- /dev/null +++ b/pkg/integration/components/confirmation_asserter.go @@ -0,0 +1,52 @@ +package components + +type ConfirmationAsserter struct { + assert *Assert + input *Input + hasCheckedTitle bool + hasCheckedContent bool +} + +func (self *ConfirmationAsserter) getViewAsserter() *ViewAsserter { + return self.assert.View("confirmation") +} + +// asserts that the confirmation view has the expected title +func (self *ConfirmationAsserter) Title(expected *matcher) *ConfirmationAsserter { + self.getViewAsserter().Title(expected) + + self.hasCheckedTitle = true + + return self +} + +// asserts that the confirmation view has the expected content +func (self *ConfirmationAsserter) Content(expected *matcher) *ConfirmationAsserter { + self.getViewAsserter().Content(expected) + + self.hasCheckedContent = true + + return self +} + +func (self *ConfirmationAsserter) Confirm() *ConfirmationAsserter { + self.checkNecessaryChecksCompleted() + + self.input.Confirm() + + return self +} + +func (self *ConfirmationAsserter) Cancel() *ConfirmationAsserter { + self.checkNecessaryChecksCompleted() + + self.input.Press(self.input.keys.Universal.Return) + + return self +} + +func (self *ConfirmationAsserter) checkNecessaryChecksCompleted() { + if !self.hasCheckedContent || !self.hasCheckedTitle { + self.assert.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") + } +} diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index 39f1991c1..ed23b6a0d 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -215,18 +215,10 @@ func (self *Input) NavigateToListItem(matcher *matcher) { } } -func (self *Input) AcceptConfirmation(title *matcher, content *matcher) { +func (self *Input) InConfirm() *ConfirmationAsserter { self.assert.InConfirm() - self.assert.CurrentView().Title(title) - self.assert.CurrentView().Content(content) - self.Confirm() -} -func (self *Input) DenyConfirmation(title *matcher, content *matcher) { - self.assert.InConfirm() - self.assert.CurrentView().Title(title) - self.assert.CurrentView().Content(content) - self.Cancel() + return &ConfirmationAsserter{assert: self.assert, input: self} } func (self *Input) Prompt(title *matcher, textToType string) { diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 01bd4edda..0452898db 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -31,7 +31,10 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Universal.Remove) - input.AcceptConfirmation(Equals("Delete Branch"), Contains("Are you sure you want to delete the branch 'branch-one'?")) + input.InConfirm(). + Title(Equals("Delete Branch")). + Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). + Confirm() assert.CurrentView().Name("localBranches"). Lines( diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index 860331215..dc5c87b03 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -31,8 +31,14 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Branches.RebaseBranch) - input.AcceptConfirmation(Equals("Rebasing"), Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")) - input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!")) + input.InConfirm(). + Title(Equals("Rebasing")). + Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). + Confirm() + input.InConfirm(). + Title(Equals("Auto-merge failed")). + Content(Contains("Conflicts!")). + Confirm() assert.CurrentView().Name("files").SelectedLine(Contains("file")) @@ -45,7 +51,10 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ assert.View("information").Content(Contains("rebasing")) - input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?")) + input.InConfirm(). + Title(Equals("continue")). + Content(Contains("all merge conflicts resolved. Continue?")). + Confirm() assert.View("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 2ef65c3aa..8ecb18e23 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -36,11 +36,17 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Branches.RebaseBranch) - input.AcceptConfirmation(Equals("Rebasing"), Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")) + input.InConfirm(). + Title(Equals("Rebasing")). + Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). + Confirm() assert.View("information").Content(Contains("rebasing")) - input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!")) + input.InConfirm(). + Title(Equals("Auto-merge failed")). + Content(Contains("Conflicts!")). + Confirm() assert.CurrentView(). Name("files"). @@ -77,7 +83,10 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentView().Name("mergeConflicts") input.PrimaryAction() - input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?")) + input.InConfirm(). + Title(Equals("continue")). + Content(Contains("all merge conflicts resolved. Continue?")). + Confirm() assert.View("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 4ed310e1d..1359c1d66 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -47,7 +47,10 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ 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.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!")) + input.InConfirm(). + Title(Equals("Auto-merge failed")). + Content(Contains("Conflicts!")). + Confirm() assert.CurrentView().Name("files") assert.CurrentView().SelectedLine(Contains("file")) @@ -61,7 +64,10 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.PrimaryAction() - input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?")) + input.InConfirm(). + Title(Equals("continue")). + Content(Contains("all merge conflicts resolved. Continue?")). + Confirm() assert.CurrentView().Name("files") assert.WorkingTreeFileCount(0) diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index a9bd6373a..63f6b1b96 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -25,7 +25,10 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ ) input.Press(keys.Commits.RevertCommit) - input.AcceptConfirmation(Equals("Revert commit"), MatchesRegexp(`Are you sure you want to revert \w+?`)) + input.InConfirm(). + Title(Equals("Revert commit")). + Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). + Confirm() assert.CurrentView().Name("commits"). Lines( diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index 8651efd39..9c02f4eef 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -69,7 +69,10 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu(Equals("Choose file content"), Contains("bar")) - input.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure you want to make this file? Up to you buddy.")) + input.InConfirm(). + Title(Equals("Are you sure?")). + Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). + Confirm() assert.WorkingTreeFileCount(1) assert.CurrentView().SelectedLine(Contains("my file")) diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index f3aa04728..060ce04a9 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -67,7 +67,10 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu(Equals("Choose file content"), Contains("bar")) - input.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure you want to make this file? Up to you buddy.")) + input.InConfirm(). + Title(Equals("Are you sure?")). + Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). + Confirm() assert.WorkingTreeFileCount(1) assert.CurrentView().SelectedLine(Contains("myfile")) diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index e44bb45d7..c9a8aa497 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -98,7 +98,10 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"}, }) - input.DenyConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?")) + input.InConfirm(). + Title(Equals("continue")). + Content(Contains("all merge conflicts resolved. Continue?")). + Cancel() discardOneByOne([]statusFile{ {status: "MD", label: "change-delete.txt", menuTitle: "change-delete.txt"}, diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 449d5f614..93a577eb9 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -36,7 +36,10 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ assert.HeadCommitMessage(Contains(mergeCommitMessage)) input.Press(keys.Commits.AmendToCommit) - input.AcceptConfirmation(Equals("Amend Commit"), Contains("Are you sure you want to amend this commit with your staged files?")) + input.InConfirm(). + Title(Equals("Amend Commit")). + Content(Contains("Are you sure you want to amend this commit with your staged files?")). + Confirm() // assuring we haven't added a brand new commit assert.CommitCount(3) diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index 183f7dd0b..cf0e3235d 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -17,6 +17,9 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(0) input.Press(keys.Universal.Quit) - input.AcceptConfirmation(Equals(""), Contains("Are you sure you want to quit?")) + input.InConfirm(). + Title(Equals("")). + Content(Contains("Are you sure you want to quit?")). + Confirm() }, }) From 8052ac4fd6f4ea96fbfb7a3ff16799ba981be82a Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 11:21:44 +1100 Subject: [PATCH 02/20] add prompt asserter --- pkg/integration/components/input.go | 9 ++- pkg/integration/components/prompt_asserter.go | 59 +++++++++++++++++++ .../tests/branch/checkout_by_name.go | 2 +- pkg/integration/tests/branch/delete.go | 2 +- pkg/integration/tests/branch/rebase.go | 6 +- .../tests/branch/rebase_and_drop.go | 6 +- .../cherry_pick/cherry_pick_conflicts.go | 4 +- pkg/integration/tests/commit/new_branch.go | 2 +- pkg/integration/tests/commit/revert.go | 2 +- .../tests/custom_commands/form_prompts.go | 4 +- .../custom_commands/menu_from_command.go | 2 +- .../tests/custom_commands/multiple_prompts.go | 4 +- pkg/integration/tests/file/discard_changes.go | 2 +- .../tests/interactive_rebase/amend_merge.go | 2 +- pkg/integration/tests/misc/confirm_on_quit.go | 2 +- pkg/integration/tests/stash/rename.go | 2 +- pkg/integration/tests/stash/stash.go | 2 +- .../stash/stash_including_untracked_files.go | 2 +- 18 files changed, 86 insertions(+), 28 deletions(-) create mode 100644 pkg/integration/components/prompt_asserter.go diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index ed23b6a0d..2d086eba5 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -215,17 +215,16 @@ func (self *Input) NavigateToListItem(matcher *matcher) { } } -func (self *Input) InConfirm() *ConfirmationAsserter { +func (self *Input) Confirmation() *ConfirmationAsserter { self.assert.InConfirm() return &ConfirmationAsserter{assert: self.assert, input: self} } -func (self *Input) Prompt(title *matcher, textToType string) { +func (self *Input) Prompt() *PromptAsserter { self.assert.InPrompt() - self.assert.CurrentView().Title(title) - self.Type(textToType) - self.Confirm() + + return &PromptAsserter{assert: self.assert, input: self} } // type some text into a prompt, then switch to the suggestions panel and expect the first diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go new file mode 100644 index 000000000..839934aaa --- /dev/null +++ b/pkg/integration/components/prompt_asserter.go @@ -0,0 +1,59 @@ +package components + +type PromptAsserter struct { + assert *Assert + input *Input + hasCheckedTitle bool +} + +func (self *PromptAsserter) getViewAsserter() *ViewAsserter { + return self.assert.View("confirmation") +} + +// asserts that the popup has the expected title +func (self *PromptAsserter) Title(expected *matcher) *PromptAsserter { + self.getViewAsserter().Title(expected) + + self.hasCheckedTitle = true + + return self +} + +// asserts on the text initially present in the prompt +func (self *PromptAsserter) InitialText(expected *matcher) *PromptAsserter { + self.getViewAsserter().Content(expected) + + return self +} + +func (self *PromptAsserter) Confirm() *PromptAsserter { + self.checkNecessaryChecksCompleted() + + self.input.Confirm() + + return self +} + +func (self *PromptAsserter) Cancel() *PromptAsserter { + self.checkNecessaryChecksCompleted() + + self.input.Press(self.input.keys.Universal.Return) + + return self +} + +func (self *PromptAsserter) Type(value string) *PromptAsserter { + self.input.Type(value) + + return self +} + +func (self *PromptAsserter) Clear() *PromptAsserter { + panic("Clear method not yet implemented!") +} + +func (self *PromptAsserter) checkNecessaryChecksCompleted() { + if !self.hasCheckedTitle { + self.assert.Fail("You must check the title of a prompt popup by calling Title() before calling Confirm()/Cancel().") + } +} diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index d3742e8f9..17fd214af 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -28,7 +28,7 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Branches.CheckoutBranchByName) - input.Prompt(Equals("Branch name:"), "new-branch") + input.Prompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() input.Alert(Equals("Branch not found"), Equals("Branch not found. Create a new branch named new-branch?")) diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 0452898db..815d40d45 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -31,7 +31,7 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Universal.Remove) - input.InConfirm(). + input.Confirmation(). Title(Equals("Delete Branch")). Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). Confirm() diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index dc5c87b03..e4f03810e 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -31,11 +31,11 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Branches.RebaseBranch) - input.InConfirm(). + input.Confirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - input.InConfirm(). + input.Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() @@ -51,7 +51,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ assert.View("information").Content(Contains("rebasing")) - input.InConfirm(). + input.Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 8ecb18e23..b1cc408ba 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -36,14 +36,14 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Branches.RebaseBranch) - input.InConfirm(). + input.Confirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() assert.View("information").Content(Contains("rebasing")) - input.InConfirm(). + input.Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() @@ -83,7 +83,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentView().Name("mergeConflicts") input.PrimaryAction() - input.InConfirm(). + input.Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index 1359c1d66..31c64664f 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -47,7 +47,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ 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.InConfirm(). + input.Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() @@ -64,7 +64,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.PrimaryAction() - input.InConfirm(). + input.Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index 1702b0973..c14e48310 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -30,7 +30,7 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Universal.New) branchName := "my-branch-name" - input.Prompt(Contains("New Branch Name"), branchName) + input.Prompt().Title(Equals("New Branch Name")).Type(branchName).Confirm() assert.CurrentBranchName(branchName) diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index 63f6b1b96..9527d5640 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -25,7 +25,7 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ ) input.Press(keys.Commits.RevertCommit) - input.InConfirm(). + input.Confirmation(). Title(Equals("Revert commit")). Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). Confirm() diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index 9c02f4eef..dbb2b3c8c 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -65,11 +65,11 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ input.Press("a") - input.Prompt(Equals("Enter a file name"), "my file") + input.Prompt().Title(Equals("Enter a file name")).Type("my file").Confirm() input.Menu(Equals("Choose file content"), Contains("bar")) - input.InConfirm(). + input.Confirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index c4fe063e2..f130af989 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -55,7 +55,7 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu(Equals("Choose commit message"), Contains("bar")) - input.Prompt(Equals("Description"), " my branch") + input.Prompt().Title(Equals("Description")).Type(" my branch").Confirm() input.SwitchToFilesView() diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index 060ce04a9..eb20876cf 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -63,11 +63,11 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ input.Press("a") - input.Prompt(Equals("Enter a file name"), "myfile") + input.Prompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() input.Menu(Equals("Choose file content"), Contains("bar")) - input.InConfirm(). + input.Confirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index c9a8aa497..9d88f49e5 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -98,7 +98,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"}, }) - input.InConfirm(). + input.Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Cancel() diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 93a577eb9..f1ea39d04 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -36,7 +36,7 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ assert.HeadCommitMessage(Contains(mergeCommitMessage)) input.Press(keys.Commits.AmendToCommit) - input.InConfirm(). + input.Confirmation(). Title(Equals("Amend Commit")). Content(Contains("Are you sure you want to amend this commit with your staged files?")). Confirm() diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index cf0e3235d..5f377eeab 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -17,7 +17,7 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(0) input.Press(keys.Universal.Quit) - input.InConfirm(). + input.Confirmation(). Title(Equals("")). Content(Contains("Are you sure you want to quit?")). Confirm() diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index 7088de423..99036b7f6 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -28,7 +28,7 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Stash.RenameStash) - input.Prompt(Equals("Rename stash: stash@{1}"), " baz") + input.Prompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() assert.CurrentView().SelectedLine(Equals("On master: foo baz")) }, diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index 23ff7e99d..996006489 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -23,7 +23,7 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu(Equals("Stash options"), MatchesRegexp("stash all changes$")) - input.Prompt(Equals("Stash changes"), "my stashed file") + input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").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 d193600df..b63796bbc 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -24,7 +24,7 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu(Equals("Stash options"), Contains("stash all changes including untracked files")) - input.Prompt(Equals("Stash changes"), "my stashed file") + input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() assert.StashCount(1) assert.WorkingTreeFileCount(0) From 926ed7b9b2f8119079c0d57f65e67dc4b93ecf7e Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 11:34:41 +1100 Subject: [PATCH 03/20] more refactoring of popup stuff --- pkg/integration/components/alert_asserter.go | 48 ++++++++++++++++ .../components/confirmation_asserter.go | 8 +-- pkg/integration/components/input.go | 26 ++------- pkg/integration/components/menu_asserter.go | 44 +++++++++++++++ pkg/integration/components/prompt_asserter.go | 56 +++++++++++++------ pkg/integration/tests/bisect/basic.go | 6 +- .../tests/bisect/from_other_branch.go | 4 +- .../tests/branch/checkout_by_name.go | 2 +- pkg/integration/tests/branch/delete.go | 2 +- pkg/integration/tests/branch/reset.go | 2 +- pkg/integration/tests/branch/suggestions.go | 7 ++- .../tests/cherry_pick/cherry_pick.go | 5 +- .../cherry_pick/cherry_pick_conflicts.go | 2 +- .../tests/custom_commands/form_prompts.go | 2 +- .../custom_commands/menu_from_command.go | 2 +- .../menu_from_commands_output.go | 2 +- .../tests/custom_commands/multiple_prompts.go | 2 +- pkg/integration/tests/diff/diff.go | 4 +- .../tests/diff/diff_and_apply_patch.go | 6 +- pkg/integration/tests/diff/diff_commits.go | 4 +- pkg/integration/tests/file/discard_changes.go | 2 +- pkg/integration/tests/stash/stash.go | 2 +- .../stash/stash_including_untracked_files.go | 2 +- 23 files changed, 173 insertions(+), 67 deletions(-) create mode 100644 pkg/integration/components/alert_asserter.go create mode 100644 pkg/integration/components/menu_asserter.go diff --git a/pkg/integration/components/alert_asserter.go b/pkg/integration/components/alert_asserter.go new file mode 100644 index 000000000..c2b85848a --- /dev/null +++ b/pkg/integration/components/alert_asserter.go @@ -0,0 +1,48 @@ +package components + +type AlertAsserter struct { + assert *Assert + input *Input + hasCheckedTitle bool + hasCheckedContent bool +} + +func (self *AlertAsserter) getViewAsserter() *ViewAsserter { + return self.assert.View("confirmation") +} + +// asserts that the alert view has the expected title +func (self *AlertAsserter) Title(expected *matcher) *AlertAsserter { + self.getViewAsserter().Title(expected) + + self.hasCheckedTitle = true + + return self +} + +// asserts that the alert view has the expected content +func (self *AlertAsserter) Content(expected *matcher) *AlertAsserter { + self.getViewAsserter().Content(expected) + + self.hasCheckedContent = true + + return self +} + +func (self *AlertAsserter) Confirm() { + self.checkNecessaryChecksCompleted() + + self.input.Confirm() +} + +func (self *AlertAsserter) Cancel() { + self.checkNecessaryChecksCompleted() + + self.input.Press(self.input.keys.Universal.Return) +} + +func (self *AlertAsserter) checkNecessaryChecksCompleted() { + if !self.hasCheckedContent || !self.hasCheckedTitle { + self.assert.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") + } +} diff --git a/pkg/integration/components/confirmation_asserter.go b/pkg/integration/components/confirmation_asserter.go index fa11e814f..c0ff9246a 100644 --- a/pkg/integration/components/confirmation_asserter.go +++ b/pkg/integration/components/confirmation_asserter.go @@ -29,20 +29,16 @@ func (self *ConfirmationAsserter) Content(expected *matcher) *ConfirmationAssert return self } -func (self *ConfirmationAsserter) Confirm() *ConfirmationAsserter { +func (self *ConfirmationAsserter) Confirm() { self.checkNecessaryChecksCompleted() self.input.Confirm() - - return self } -func (self *ConfirmationAsserter) Cancel() *ConfirmationAsserter { +func (self *ConfirmationAsserter) Cancel() { self.checkNecessaryChecksCompleted() self.input.Press(self.input.keys.Universal.Return) - - return self } func (self *ConfirmationAsserter) checkNecessaryChecksCompleted() { diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index 2d086eba5..91048dfb7 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -227,28 +227,14 @@ func (self *Input) Prompt() *PromptAsserter { return &PromptAsserter{assert: self.assert, input: self} } -// 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.CurrentView().Title(title) - self.Type(textToType) - self.Press(self.keys.Universal.TogglePanel) - self.assert.CurrentView().Name("suggestions") - self.assert.CurrentView().SelectedLine(expectedFirstOption) - self.Confirm() +func (self *Input) Alert() *AlertAsserter { + self.assert.InAlert() + + return &AlertAsserter{assert: self.assert, input: self} } -func (self *Input) Menu(title *matcher, optionToSelect *matcher) { +func (self *Input) Menu() *MenuAsserter { self.assert.InMenu() - self.assert.CurrentView().Title(title) - self.NavigateToListItem(optionToSelect) - self.Confirm() -} -func (self *Input) Alert(title *matcher, content *matcher) { - self.assert.InListContext() - self.assert.CurrentView().Title(title) - self.assert.CurrentView().Content(content) - self.Confirm() + return &MenuAsserter{assert: self.assert, input: self} } diff --git a/pkg/integration/components/menu_asserter.go b/pkg/integration/components/menu_asserter.go new file mode 100644 index 000000000..7c5e2e5f9 --- /dev/null +++ b/pkg/integration/components/menu_asserter.go @@ -0,0 +1,44 @@ +package components + +type MenuAsserter struct { + assert *Assert + input *Input + hasCheckedTitle bool +} + +func (self *MenuAsserter) getViewAsserter() *ViewAsserter { + return self.assert.View("menu") +} + +// asserts that the popup has the expected title +func (self *MenuAsserter) Title(expected *matcher) *MenuAsserter { + self.getViewAsserter().Title(expected) + + self.hasCheckedTitle = true + + return self +} + +func (self *MenuAsserter) Confirm() { + self.checkNecessaryChecksCompleted() + + self.input.Confirm() +} + +func (self *MenuAsserter) Cancel() { + self.checkNecessaryChecksCompleted() + + self.input.Press(self.input.keys.Universal.Return) +} + +func (self *MenuAsserter) Select(option *matcher) *MenuAsserter { + self.input.NavigateToListItem(option) + + return self +} + +func (self *MenuAsserter) checkNecessaryChecksCompleted() { + if !self.hasCheckedTitle { + self.assert.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().") + } +} diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go index 839934aaa..01d1ed8f7 100644 --- a/pkg/integration/components/prompt_asserter.go +++ b/pkg/integration/components/prompt_asserter.go @@ -26,22 +26,6 @@ func (self *PromptAsserter) InitialText(expected *matcher) *PromptAsserter { return self } -func (self *PromptAsserter) Confirm() *PromptAsserter { - self.checkNecessaryChecksCompleted() - - self.input.Confirm() - - return self -} - -func (self *PromptAsserter) Cancel() *PromptAsserter { - self.checkNecessaryChecksCompleted() - - self.input.Press(self.input.keys.Universal.Return) - - return self -} - func (self *PromptAsserter) Type(value string) *PromptAsserter { self.input.Type(value) @@ -52,8 +36,48 @@ func (self *PromptAsserter) Clear() *PromptAsserter { panic("Clear method not yet implemented!") } +func (self *PromptAsserter) Confirm() { + self.checkNecessaryChecksCompleted() + + self.input.Confirm() +} + +func (self *PromptAsserter) Cancel() { + self.checkNecessaryChecksCompleted() + + self.input.Press(self.input.keys.Universal.Return) +} + func (self *PromptAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedTitle { self.assert.Fail("You must check the title of a prompt popup by calling Title() before calling Confirm()/Cancel().") } } + +func (self *PromptAsserter) SuggestionLines(matchers ...*matcher) *PromptAsserter { + self.assert.View("suggestions").Lines(matchers...) + + return self +} + +func (self *PromptAsserter) SuggestionTopLines(matchers ...*matcher) *PromptAsserter { + self.assert.View("suggestions").TopLines(matchers...) + + return self +} + +func (self *PromptAsserter) SelectFirstSuggestion() *PromptAsserter { + self.input.Press(self.input.keys.Universal.TogglePanel) + self.assert.CurrentView().Name("suggestions") + + return self +} + +func (self *PromptAsserter) SelectSuggestion(matcher *matcher) *PromptAsserter { + self.input.Press(self.input.keys.Universal.TogglePanel) + self.assert.CurrentView().Name("suggestions") + + self.input.NavigateToListItem(matcher) + + return self +} diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index 45d66fa18..86e58b681 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -22,12 +22,12 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ ) { markCommitAsBad := func() { input.Press(keys.Commits.ViewBisectOptions) - input.Menu(Equals("Bisect"), MatchesRegexp(`mark .* as bad`)) + input.Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as bad`)).Confirm() } markCommitAsGood := func() { input.Press(keys.Commits.ViewBisectOptions) - input.Menu(Equals("Bisect"), MatchesRegexp(`mark .* as good`)) + input.Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() } assert.AtLeastOneCommit() @@ -62,7 +62,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ markCommitAsGood() // commit 5 is the culprit because we marked 4 as good and 5 as bad. - input.Alert(Equals("Bisect complete"), MatchesRegexp("(?s)commit 05.*Do you want to reset")) + input.Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() assert.CurrentView().Name("commits").Content(Contains("commit 04")) assert.View("information").Content(DoesNotContain("bisecting")) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index cb31af972..40308246e 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -40,9 +40,9 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Commits.ViewBisectOptions) - input.Menu(Equals("Bisect"), MatchesRegexp(`mark .* as good`)) + input.Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() - input.Alert(Equals("Bisect complete"), MatchesRegexp(`(?s)commit 08.*Do you want to reset`)) + input.Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() assert.View("information").Content(DoesNotContain("bisecting")) diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index 17fd214af..e855b7103 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -30,7 +30,7 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ input.Prompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() - input.Alert(Equals("Branch not found"), Equals("Branch not found. Create a new branch named new-branch?")) + input.Alert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() assert.CurrentView().Name("localBranches"). Lines( diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 815d40d45..c28668bb5 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -26,7 +26,7 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ ) input.Press(keys.Universal.Remove) - input.Alert(Equals("Error"), Contains("You cannot delete the checked out branch!")) + input.Alert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() input.NextItem() diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index 8be35e4ec..821373934 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -36,7 +36,7 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Commits.ViewResetOptions) - input.Menu(Contains("reset to other-branch"), Contains("hard reset")) + input.Menu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() // ensure that we've returned from the menu before continuing assert.CurrentView().Name("localBranches") diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index 7631ad735..f9399296d 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -27,7 +27,12 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ // we expect the first suggestion to be the branch we want because it most // closely matches what we typed in - input.Typeahead(Equals("Branch name:"), "branch-to", Contains("branch-to-checkout")) + input.Prompt(). + Title(Equals("Branch name:")). + Type("branch-to"). + SuggestionTopLines(Contains("branch-to-checkout")). + SelectFirstSuggestion(). + Confirm() 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 e79e35b19..631685577 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -58,7 +58,10 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ ) 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.Alert(). + Title(Equals("Cherry-Pick")). + Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). + Confirm() assert.CurrentView().Name("commits").Lines( Contains("four"), diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index 31c64664f..8efb94e5d 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -45,7 +45,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ ) 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.Alert().Title(Equals("Cherry-Pick")).Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).Confirm() input.Confirmation(). Title(Equals("Auto-merge failed")). diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index dbb2b3c8c..fa6495a93 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -67,7 +67,7 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ input.Prompt().Title(Equals("Enter a file name")).Type("my file").Confirm() - input.Menu(Equals("Choose file content"), Contains("bar")) + input.Menu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() input.Confirmation(). Title(Equals("Are you sure?")). diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index f130af989..d9b9fab05 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -53,7 +53,7 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ input.Press("a") - input.Menu(Equals("Choose commit message"), Contains("bar")) + input.Menu().Title(Equals("Choose commit message")).Select(Contains("bar")).Confirm() input.Prompt().Title(Equals("Description")).Type(" my branch").Confirm() 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 68c4db0f6..d17cb1176 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -60,7 +60,7 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ SelectedLine(Equals("branch")) input.Confirm() - input.Menu(Equals("Branch:"), Equals("master")) + input.Menu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() assert.CurrentBranchName("master") }, diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index eb20876cf..9b77a05bf 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -65,7 +65,7 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ input.Prompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() - input.Menu(Equals("Choose file content"), Contains("bar")) + input.Menu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() input.Confirmation(). Title(Equals("Are you sure?")). diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index 4bba36de8..e0fc214b2 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -29,7 +29,7 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ Contains("branch-b"), ) input.Press(keys.Universal.DiffingMenu) - input.Menu(Equals("Diffing"), Contains(`diff branch-a`)) + input.Menu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() assert.CurrentView().Name("localBranches") @@ -51,7 +51,7 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentView().Name("localBranches") input.Press(keys.Universal.DiffingMenu) - input.Menu(Equals("Diffing"), Contains("reverse diff direction")) + input.Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() assert.View("information").Content(Contains("showing output for: git diff branch-a branch-b -R")) assert.MainView().Content(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 e963bb296..e6dfe5a97 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -30,7 +30,7 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Universal.DiffingMenu) - input.Menu(Equals("Diffing"), Equals("diff branch-a")) + input.Menu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() assert.CurrentView().Name("localBranches") @@ -52,13 +52,13 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ input.PrimaryAction() input.Press(keys.Universal.DiffingMenu) - input.Menu(Equals("Diffing"), Contains("exit diff mode")) + input.Menu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() assert.View("information").Content(DoesNotContain("building patch")) 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.Menu().Title(Equals("Patch Options")).Select(MatchesRegexp("apply patch$")).Confirm() input.SwitchToFilesView() diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index efa44d818..e4db05f18 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -28,7 +28,7 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ ) input.Press(keys.Universal.DiffingMenu) - input.Menu(Equals("Diffing"), MatchesRegexp(`diff \w+`)) + input.Menu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() assert.NotInPopup() @@ -41,7 +41,7 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ assert.MainView().Content(Contains("-second line\n-third line")) input.Press(keys.Universal.DiffingMenu) - input.Menu(Equals("Diffing"), Contains("reverse diff direction")) + input.Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() assert.NotInPopup() assert.MainView().Content(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 9d88f49e5..e965385ec 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -84,7 +84,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ for _, file := range files { assert.CurrentView().SelectedLine(Contains(file.status + " " + file.label)) input.Press(keys.Universal.Remove) - input.Menu(Equals(file.menuTitle), Contains("discard all changes")) + input.Menu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() } } diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index 996006489..8f1281bc3 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -21,7 +21,7 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Files.ViewStashOptions) - input.Menu(Equals("Stash options"), MatchesRegexp("stash all changes$")) + input.Menu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() diff --git a/pkg/integration/tests/stash/stash_including_untracked_files.go b/pkg/integration/tests/stash/stash_including_untracked_files.go index b63796bbc..51cdbbc25 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -22,7 +22,7 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Files.ViewStashOptions) - input.Menu(Equals("Stash options"), Contains("stash all changes including untracked files")) + input.Menu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() From b64f55518bc0f986662b54bbaaefecc692555100 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 11:55:30 +1100 Subject: [PATCH 04/20] refactor commit message stuff in integration tests --- .../commit_message_panel_asserter.go | 41 +++++++++++++++++++ pkg/integration/components/input.go | 6 +++ pkg/integration/tests/commit/commit.go | 5 +-- .../tests/commit/commit_multiline.go | 7 +--- .../tests/commit/staged_without_hooks.go | 6 +-- pkg/integration/tests/commit/unstaged.go | 5 +-- 6 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 pkg/integration/components/commit_message_panel_asserter.go diff --git a/pkg/integration/components/commit_message_panel_asserter.go b/pkg/integration/components/commit_message_panel_asserter.go new file mode 100644 index 000000000..f7923282e --- /dev/null +++ b/pkg/integration/components/commit_message_panel_asserter.go @@ -0,0 +1,41 @@ +package components + +type CommitMessagePanelAsserter struct { + assert *Assert + input *Input +} + +func (self *CommitMessagePanelAsserter) getViewAsserter() *ViewAsserter { + return self.assert.View("commitMessage") +} + +// asserts on the text initially present in the prompt +func (self *CommitMessagePanelAsserter) InitialText(expected *matcher) *CommitMessagePanelAsserter { + self.getViewAsserter().Content(expected) + + return self +} + +func (self *CommitMessagePanelAsserter) Type(value string) *CommitMessagePanelAsserter { + self.input.Type(value) + + return self +} + +func (self *CommitMessagePanelAsserter) AddNewline() *CommitMessagePanelAsserter { + self.input.Press(self.input.keys.Universal.AppendNewline) + + return self +} + +func (self *CommitMessagePanelAsserter) Clear() *CommitMessagePanelAsserter { + panic("Clear method not yet implemented!") +} + +func (self *CommitMessagePanelAsserter) Confirm() { + self.input.Confirm() +} + +func (self *CommitMessagePanelAsserter) Cancel() { + self.input.Press(self.input.keys.Universal.Return) +} diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index 91048dfb7..c5d808588 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -238,3 +238,9 @@ func (self *Input) Menu() *MenuAsserter { return &MenuAsserter{assert: self.assert, input: self} } + +func (self *Input) CommitMessagePanel() *CommitMessagePanelAsserter { + self.assert.InCommitMessagePanel() + + return &CommitMessagePanelAsserter{assert: self.assert, input: self} +} diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index a20b0df34..cda9f63e0 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -22,10 +22,9 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ input.PrimaryAction() input.Press(keys.Files.CommitChanges) - assert.InCommitMessagePanel() commitMessage := "my commit message" - input.Type(commitMessage) - input.Confirm() + + input.CommitMessagePanel().Type(commitMessage).Confirm() assert.CommitCount(1) assert.HeadCommitMessage(Equals(commitMessage)) diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index d19e09a72..4d6ba883a 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -19,12 +19,7 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ input.PrimaryAction() input.Press(keys.Files.CommitChanges) - assert.InCommitMessagePanel() - input.Type("first line") - input.Press(keys.Universal.AppendNewline) - input.Press(keys.Universal.AppendNewline) - input.Type("third line") - input.Confirm() + input.CommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() assert.CommitCount(1) assert.HeadCommitMessage(Equals("first line")) diff --git a/pkg/integration/tests/commit/staged_without_hooks.go b/pkg/integration/tests/commit/staged_without_hooks.go index e2f0752f0..95fa72e7e 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -40,11 +40,9 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ assert.View("staging").Content(Contains("+myfile content").DoesNotContain("+with a second line")) input.Press(keys.Files.CommitChangesWithoutHook) - assert.InCommitMessagePanel() - assert.CurrentView().Content(Contains("WIP")) + commitMessage := ": my commit message" - input.Type(commitMessage) - input.Confirm() + input.CommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() assert.CommitCount(1) assert.HeadCommitMessage(Equals("WIP" + commitMessage)) diff --git a/pkg/integration/tests/commit/unstaged.go b/pkg/integration/tests/commit/unstaged.go index 6e7e2a307..f46c06a87 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -30,10 +30,9 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ assert.View("stagingSecondary").Content(Contains("+myfile content")) input.Press(keys.Files.CommitChanges) - assert.InCommitMessagePanel() + commitMessage := "my commit message" - input.Type(commitMessage) - input.Confirm() + input.CommitMessagePanel().Type(commitMessage).Confirm() assert.CommitCount(1) assert.HeadCommitMessage(Equals(commitMessage)) From be30cbb37509f09c53265aa39d89cac1f6cd65c2 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 15:07:11 +1100 Subject: [PATCH 05/20] add view asserter getter struct --- pkg/integration/components/alert_asserter.go | 2 +- pkg/integration/components/assert.go | 44 ++++++++++++------- .../commit_message_panel_asserter.go | 2 +- .../components/confirmation_asserter.go | 2 +- pkg/integration/components/input.go | 18 ++++---- pkg/integration/components/menu_asserter.go | 2 +- pkg/integration/components/prompt_asserter.go | 10 ++--- pkg/integration/tests/bisect/basic.go | 14 +++--- .../tests/bisect/from_other_branch.go | 8 ++-- .../tests/branch/checkout_by_name.go | 4 +- pkg/integration/tests/branch/delete.go | 4 +- pkg/integration/tests/branch/rebase.go | 14 +++--- .../tests/branch/rebase_and_drop.go | 18 ++++---- pkg/integration/tests/branch/reset.go | 8 ++-- .../tests/cherry_pick/cherry_pick.go | 16 +++---- .../cherry_pick/cherry_pick_conflicts.go | 26 +++++------ .../tests/commit/commit_multiline.go | 2 +- pkg/integration/tests/commit/new_branch.go | 4 +- pkg/integration/tests/commit/revert.go | 6 +-- pkg/integration/tests/commit/staged.go | 22 +++++----- .../tests/commit/staged_without_hooks.go | 16 +++---- pkg/integration/tests/commit/unstaged.go | 10 ++--- .../tests/custom_commands/basic.go | 2 +- .../tests/custom_commands/form_prompts.go | 4 +- .../custom_commands/menu_from_command.go | 4 +- .../menu_from_commands_output.go | 2 +- .../tests/custom_commands/multiple_prompts.go | 4 +- pkg/integration/tests/diff/diff.go | 26 +++++------ .../tests/diff/diff_and_apply_patch.go | 28 ++++++------ pkg/integration/tests/diff/diff_commits.go | 14 +++--- .../tests/file/dir_with_untracked_file.go | 2 +- pkg/integration/tests/file/discard_changes.go | 2 +- .../tests/interactive_rebase/amend_merge.go | 2 +- .../tests/interactive_rebase/one.go | 12 ++--- pkg/integration/tests/stash/rename.go | 4 +- 35 files changed, 184 insertions(+), 174 deletions(-) diff --git a/pkg/integration/components/alert_asserter.go b/pkg/integration/components/alert_asserter.go index c2b85848a..9dc2d32ab 100644 --- a/pkg/integration/components/alert_asserter.go +++ b/pkg/integration/components/alert_asserter.go @@ -8,7 +8,7 @@ type AlertAsserter struct { } func (self *AlertAsserter) getViewAsserter() *ViewAsserter { - return self.assert.View("confirmation") + return self.assert.Views().ByName("confirmation") } // asserts that the alert view has the expected title diff --git a/pkg/integration/components/assert.go b/pkg/integration/components/assert.go index ac6b99f0e..b4be669c5 100644 --- a/pkg/integration/components/assert.go +++ b/pkg/integration/components/assert.go @@ -182,34 +182,44 @@ func (self *Assert) FileSystemPathNotPresent(path string) { }) } -func (self *Assert) CurrentView() *ViewAsserter { +func (self *Assert) Views() *ViewAsserterGetter { + return &ViewAsserterGetter{ + assert: self, + } +} + +type ViewAsserterGetter struct { + assert *Assert +} + +func (self *ViewAsserterGetter) Current() *ViewAsserter { return &ViewAsserter{ context: "current view", - getView: func() *gocui.View { return self.gui.CurrentContext().GetView() }, - assert: self, + getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() }, + assert: self.assert, } } -func (self *Assert) View(viewName string) *ViewAsserter { - return &ViewAsserter{ - context: fmt.Sprintf("%s view", viewName), - getView: func() *gocui.View { return self.gui.View(viewName) }, - assert: self, - } -} - -func (self *Assert) MainView() *ViewAsserter { +func (self *ViewAsserterGetter) Main() *ViewAsserter { return &ViewAsserter{ context: "main view", - getView: func() *gocui.View { return self.gui.MainView() }, - assert: self, + getView: func() *gocui.View { return self.assert.gui.MainView() }, + assert: self.assert, } } -func (self *Assert) SecondaryView() *ViewAsserter { +func (self *ViewAsserterGetter) Secondary() *ViewAsserter { return &ViewAsserter{ context: "secondary view", - getView: func() *gocui.View { return self.gui.SecondaryView() }, - assert: self, + getView: func() *gocui.View { return self.assert.gui.SecondaryView() }, + assert: self.assert, + } +} + +func (self *ViewAsserterGetter) ByName(viewName string) *ViewAsserter { + return &ViewAsserter{ + context: fmt.Sprintf("%s view", viewName), + getView: func() *gocui.View { return self.assert.gui.View(viewName) }, + assert: self.assert, } } diff --git a/pkg/integration/components/commit_message_panel_asserter.go b/pkg/integration/components/commit_message_panel_asserter.go index f7923282e..6ffb6b80c 100644 --- a/pkg/integration/components/commit_message_panel_asserter.go +++ b/pkg/integration/components/commit_message_panel_asserter.go @@ -6,7 +6,7 @@ type CommitMessagePanelAsserter struct { } func (self *CommitMessagePanelAsserter) getViewAsserter() *ViewAsserter { - return self.assert.View("commitMessage") + return self.assert.Views().ByName("commitMessage") } // asserts on the text initially present in the prompt diff --git a/pkg/integration/components/confirmation_asserter.go b/pkg/integration/components/confirmation_asserter.go index c0ff9246a..371e46028 100644 --- a/pkg/integration/components/confirmation_asserter.go +++ b/pkg/integration/components/confirmation_asserter.go @@ -8,7 +8,7 @@ type ConfirmationAsserter struct { } func (self *ConfirmationAsserter) getViewAsserter() *ViewAsserter { - return self.assert.View("confirmation") + return self.assert.Views().ByName("confirmation") } // asserts that the confirmation view has the expected title diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index c5d808588..014a74d5d 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -48,7 +48,7 @@ func (self *Input) SwitchToStatusWindow() { // switch to status window and assert that the status view is on top func (self *Input) SwitchToStatusView() { self.SwitchToStatusWindow() - self.assert.CurrentView().Name("status") + self.assert.Views().Current().Name("status") } func (self *Input) SwitchToFilesWindow() { @@ -59,7 +59,7 @@ func (self *Input) SwitchToFilesWindow() { // switch to files window and assert that the files view is on top func (self *Input) SwitchToFilesView() { self.SwitchToFilesWindow() - self.assert.CurrentView().Name("files") + self.assert.Views().Current().Name("files") } func (self *Input) SwitchToBranchesWindow() { @@ -70,7 +70,7 @@ func (self *Input) SwitchToBranchesWindow() { // switch to branches window and assert that the branches view is on top func (self *Input) SwitchToBranchesView() { self.SwitchToBranchesWindow() - self.assert.CurrentView().Name("localBranches") + self.assert.Views().Current().Name("localBranches") } func (self *Input) SwitchToCommitsWindow() { @@ -81,7 +81,7 @@ func (self *Input) SwitchToCommitsWindow() { // switch to commits window and assert that the commits view is on top func (self *Input) SwitchToCommitsView() { self.SwitchToCommitsWindow() - self.assert.CurrentView().Name("commits") + self.assert.Views().Current().Name("commits") } func (self *Input) SwitchToStashWindow() { @@ -92,7 +92,7 @@ func (self *Input) SwitchToStashWindow() { // switch to stash window and assert that the stash view is on top func (self *Input) SwitchToStashView() { self.SwitchToStashWindow() - self.assert.CurrentView().Name("stash") + self.assert.Views().Current().Name("stash") } func (self *Input) Type(content string) { @@ -133,7 +133,7 @@ func (self *Input) PreviousItem() { func (self *Input) ContinueMerge() { self.Press(self.keys.Universal.CreateRebaseOptionsMenu) - self.assert.CurrentView().SelectedLine(Contains("continue")) + self.assert.Views().Current().SelectedLine(Contains("continue")) self.Confirm() } @@ -197,20 +197,20 @@ func (self *Input) NavigateToListItem(matcher *matcher) { selectedLineIdx := view.SelectedLineIdx() if selectedLineIdx == matchIndex { - self.assert.CurrentView().SelectedLine(matcher) + self.assert.Views().Current().SelectedLine(matcher) return } if selectedLineIdx < matchIndex { for i := selectedLineIdx; i < matchIndex; i++ { self.NextItem() } - self.assert.CurrentView().SelectedLine(matcher) + self.assert.Views().Current().SelectedLine(matcher) return } else { for i := selectedLineIdx; i > matchIndex; i-- { self.PreviousItem() } - self.assert.CurrentView().SelectedLine(matcher) + self.assert.Views().Current().SelectedLine(matcher) return } } diff --git a/pkg/integration/components/menu_asserter.go b/pkg/integration/components/menu_asserter.go index 7c5e2e5f9..ab2256320 100644 --- a/pkg/integration/components/menu_asserter.go +++ b/pkg/integration/components/menu_asserter.go @@ -7,7 +7,7 @@ type MenuAsserter struct { } func (self *MenuAsserter) getViewAsserter() *ViewAsserter { - return self.assert.View("menu") + return self.assert.Views().ByName("menu") } // asserts that the popup has the expected title diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go index 01d1ed8f7..079cc4d3f 100644 --- a/pkg/integration/components/prompt_asserter.go +++ b/pkg/integration/components/prompt_asserter.go @@ -7,7 +7,7 @@ type PromptAsserter struct { } func (self *PromptAsserter) getViewAsserter() *ViewAsserter { - return self.assert.View("confirmation") + return self.assert.Views().ByName("confirmation") } // asserts that the popup has the expected title @@ -55,27 +55,27 @@ func (self *PromptAsserter) checkNecessaryChecksCompleted() { } func (self *PromptAsserter) SuggestionLines(matchers ...*matcher) *PromptAsserter { - self.assert.View("suggestions").Lines(matchers...) + self.assert.Views().ByName("suggestions").Lines(matchers...) return self } func (self *PromptAsserter) SuggestionTopLines(matchers ...*matcher) *PromptAsserter { - self.assert.View("suggestions").TopLines(matchers...) + self.assert.Views().ByName("suggestions").TopLines(matchers...) return self } func (self *PromptAsserter) SelectFirstSuggestion() *PromptAsserter { self.input.Press(self.input.keys.Universal.TogglePanel) - self.assert.CurrentView().Name("suggestions") + self.assert.Views().Current().Name("suggestions") return self } func (self *PromptAsserter) SelectSuggestion(matcher *matcher) *PromptAsserter { self.input.Press(self.input.keys.Universal.TogglePanel) - self.assert.CurrentView().Name("suggestions") + self.assert.Views().Current().Name("suggestions") self.input.NavigateToListItem(matcher) diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index 86e58b681..7e2a21a61 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -34,28 +34,28 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToCommitsView() - assert.CurrentView().SelectedLine(Contains("commit 10")) + assert.Views().Current().SelectedLine(Contains("commit 10")) input.NavigateToListItem(Contains("commit 09")) markCommitAsBad() - assert.View("information").Content(Contains("bisecting")) + assert.Views().ByName("information").Content(Contains("bisecting")) - assert.CurrentView().Name("commits").SelectedLine(Contains("<-- bad")) + assert.Views().Current().Name("commits").SelectedLine(Contains("<-- bad")) input.NavigateToListItem(Contains("commit 02")) markCommitAsGood() // lazygit will land us in the commit between our good and bad commits. - assert.CurrentView(). + assert.Views().Current(). Name("commits"). SelectedLine(Contains("commit 05").Contains("<-- current")) markCommitAsBad() - assert.CurrentView(). + assert.Views().Current(). Name("commits"). SelectedLine(Contains("commit 04").Contains("<-- current")) @@ -64,7 +64,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ // commit 5 is the culprit because we marked 4 as good and 5 as bad. input.Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() - assert.CurrentView().Name("commits").Content(Contains("commit 04")) - assert.View("information").Content(DoesNotContain("bisecting")) + assert.Views().Current().Name("commits").Content(Contains("commit 04")) + assert.Views().ByName("information").Content(DoesNotContain("bisecting")) }, }) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 40308246e..255b39542 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -24,13 +24,13 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - assert.View("information").Content(Contains("bisecting")) + assert.Views().ByName("information").Content(Contains("bisecting")) assert.AtLeastOneCommit() input.SwitchToCommitsView() - assert.CurrentView().TopLines( + assert.Views().Current().TopLines( MatchesRegexp(`<-- bad.*commit 08`), MatchesRegexp(`<-- current.*commit 07`), MatchesRegexp(`\?.*commit 06`), @@ -44,10 +44,10 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ input.Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() - assert.View("information").Content(DoesNotContain("bisecting")) + assert.Views().ByName("information").Content(DoesNotContain("bisecting")) // back in master branch which just had the one commit - assert.CurrentView().Name("commits").Lines( + assert.Views().Current().Name("commits").Lines( Contains("only commit on master"), ) }, diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index e855b7103..ccf75a831 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -20,7 +20,7 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("master"), Contains("@"), ) @@ -32,7 +32,7 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ input.Alert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() - assert.CurrentView().Name("localBranches"). + assert.Views().Current().Name("localBranches"). Lines( MatchesRegexp(`\*.*new-branch`), Contains("master"), diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index c28668bb5..08b4e8f62 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -19,7 +19,7 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( MatchesRegexp(`\*.*branch-two`), MatchesRegexp(`branch-one`), MatchesRegexp(`master`), @@ -36,7 +36,7 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). Confirm() - assert.CurrentView().Name("localBranches"). + assert.Views().Current().Name("localBranches"). Lines( MatchesRegexp(`\*.*branch-two`), MatchesRegexp(`master`).IsSelected(), diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index e4f03810e..ab3302068 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -17,13 +17,13 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.View("localBranches").Lines( + assert.Views().ByName("localBranches").Lines( Contains("first-change-branch"), Contains("second-change-branch"), Contains("original-branch"), ) - assert.View("commits").TopLines( + assert.Views().ByName("commits").TopLines( Contains("first change"), Contains("original"), ) @@ -40,25 +40,25 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Conflicts!")). Confirm() - assert.CurrentView().Name("files").SelectedLine(Contains("file")) + assert.Views().Current().Name("files").SelectedLine(Contains("file")) // not using Confirm() convenience method because I suspect we might change this // keybinding to something more bespoke input.Press(keys.Universal.Confirm) - assert.CurrentView().Name("mergeConflicts") + assert.Views().Current().Name("mergeConflicts") input.PrimaryAction() - assert.View("information").Content(Contains("rebasing")) + assert.Views().ByName("information").Content(Contains("rebasing")) input.Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - assert.View("information").Content(DoesNotContain("rebasing")) + assert.Views().ByName("information").Content(DoesNotContain("rebasing")) - assert.View("commits").TopLines( + assert.Views().ByName("commits").TopLines( Contains("second-change-branch unrelated change"), Contains("second change"), Contains("original"), diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index b1cc408ba..1c77dbefc 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -20,13 +20,13 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("first-change-branch"), Contains("second-change-branch"), Contains("original-branch"), ) - assert.View("commits").TopLines( + assert.Views().ByName("commits").TopLines( Contains("to keep").IsSelected(), Contains("to remove"), Contains("first change"), @@ -41,19 +41,19 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - assert.View("information").Content(Contains("rebasing")) + assert.Views().ByName("information").Content(Contains("rebasing")) input.Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() - assert.CurrentView(). + assert.Views().Current(). Name("files"). SelectedLine(MatchesRegexp("UU.*file")) input.SwitchToCommitsView() - assert.CurrentView(). + assert.Views().Current(). TopLines( MatchesRegexp(`pick.*to keep`).IsSelected(), MatchesRegexp(`pick.*to remove`), @@ -65,7 +65,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() input.Press(keys.Universal.Remove) - assert.CurrentView(). + assert.Views().Current(). TopLines( MatchesRegexp(`pick.*to keep`), MatchesRegexp(`drop.*to remove`).IsSelected(), @@ -80,7 +80,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ // keybinding to something more bespoke input.Press(keys.Universal.Confirm) - assert.CurrentView().Name("mergeConflicts") + assert.Views().Current().Name("mergeConflicts") input.PrimaryAction() input.Confirmation(). @@ -88,9 +88,9 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - assert.View("information").Content(DoesNotContain("rebasing")) + assert.Views().ByName("information").Content(DoesNotContain("rebasing")) - assert.View("commits").TopLines( + assert.Views().ByName("commits").TopLines( Contains("to keep"), Contains("second-change-branch unrelated change").IsSelected(), Contains("second change"), diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index 821373934..fec6aea7a 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -21,14 +21,14 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ shell.EmptyCommit("current-branch commit") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.View("commits").Lines( + assert.Views().ByName("commits").Lines( Contains("current-branch commit"), Contains("root commit"), ) input.SwitchToBranchesView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("current-branch"), Contains("other-branch"), ) @@ -39,11 +39,11 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() // ensure that we've returned from the menu before continuing - assert.CurrentView().Name("localBranches") + assert.Views().Current().Name("localBranches") // assert that we now have the expected commits in the commit panel input.SwitchToCommitsView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("other-branch commit"), Contains("root commit"), ) diff --git a/pkg/integration/tests/cherry_pick/cherry_pick.go b/pkg/integration/tests/cherry_pick/cherry_pick.go index 631685577..f832bfe83 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -26,7 +26,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("first-branch"), Contains("second-branch"), Contains("master"), @@ -36,7 +36,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ input.Enter() - assert.CurrentView().Name("subCommits").Lines( + assert.Views().Current().Name("subCommits").Lines( Contains("four"), Contains("three"), Contains("base"), @@ -44,14 +44,14 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ // copy commits 'four' and 'three' input.Press(keys.Commits.CherryPickCopy) - assert.View("information").Content(Contains("1 commit copied")) + assert.Views().ByName("information").Content(Contains("1 commit copied")) input.NextItem() input.Press(keys.Commits.CherryPickCopy) - assert.View("information").Content(Contains("2 commits copied")) + assert.Views().ByName("information").Content(Contains("2 commits copied")) input.SwitchToCommitsView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("two"), Contains("one"), Contains("base"), @@ -63,7 +63,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). Confirm() - assert.CurrentView().Name("commits").Lines( + assert.Views().Current().Name("commits").Lines( Contains("four"), Contains("three"), Contains("two"), @@ -71,8 +71,8 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ Contains("base"), ) - assert.View("information").Content(Contains("2 commits copied")) + assert.Views().ByName("information").Content(Contains("2 commits copied")) input.Press(keys.Universal.Return) - assert.View("information").Content(DoesNotContain("commits copied")) + assert.Views().ByName("information").Content(DoesNotContain("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 8efb94e5d..b0be4b48e 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -16,7 +16,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("first-change-branch"), Contains("second-change-branch"), Contains("original-branch"), @@ -26,21 +26,21 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ input.Enter() - assert.CurrentView().Name("subCommits").TopLines( + assert.Views().Current().Name("subCommits").TopLines( Contains("second-change-branch unrelated change"), Contains("second change"), ) input.Press(keys.Commits.CherryPickCopy) - assert.View("information").Content(Contains("1 commit copied")) + assert.Views().ByName("information").Content(Contains("1 commit copied")) input.NextItem() input.Press(keys.Commits.CherryPickCopy) - assert.View("information").Content(Contains("2 commits copied")) + assert.Views().ByName("information").Content(Contains("2 commits copied")) input.SwitchToCommitsView() - assert.CurrentView().TopLines( + assert.Views().Current().TopLines( Contains("first change"), ) @@ -52,14 +52,14 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Conflicts!")). Confirm() - assert.CurrentView().Name("files") - assert.CurrentView().SelectedLine(Contains("file")) + assert.Views().Current().Name("files") + assert.Views().Current().SelectedLine(Contains("file")) // not using Confirm() convenience method because I suspect we might change this // keybinding to something more bespoke input.Press(keys.Universal.Confirm) - assert.CurrentView().Name("mergeConflicts") + assert.Views().Current().Name("mergeConflicts") // picking 'Second change' input.NextItem() input.PrimaryAction() @@ -69,12 +69,12 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - assert.CurrentView().Name("files") + assert.Views().Current().Name("files") assert.WorkingTreeFileCount(0) input.SwitchToCommitsView() - assert.CurrentView().TopLines( + assert.Views().Current().TopLines( Contains("second-change-branch unrelated change"), Contains("second change"), Contains("first change"), @@ -83,12 +83,12 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ // because we picked 'Second change' when resolving the conflict, // we now see this commit as having replaced First Change with Second Change, // as opposed to replacing 'Original' with 'Second change' - assert.MainView(). + assert.Views().Main(). Content(Contains("-First Change")). Content(Contains("+Second Change")) - assert.View("information").Content(Contains("2 commits copied")) + assert.Views().ByName("information").Content(Contains("2 commits copied")) input.Press(keys.Universal.Return) - assert.View("information").Content(DoesNotContain("commits copied")) + assert.Views().ByName("information").Content(DoesNotContain("commits copied")) }, }) diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index 4d6ba883a..eb0723c39 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -25,6 +25,6 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ assert.HeadCommitMessage(Equals("first line")) input.SwitchToCommitsView() - assert.MainView().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) + assert.Views().Main().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) }, }) diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index c14e48310..a4001df8d 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -20,7 +20,7 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(3) input.SwitchToCommitsView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("commit 3"), Contains("commit 2"), Contains("commit 1"), @@ -34,7 +34,7 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentBranchName(branchName) - assert.View("commits").Lines( + assert.Views().ByName("commits").Lines( Contains("commit 2"), Contains("commit 1"), ) diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index 9527d5640..5ce7ac12b 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -20,7 +20,7 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToCommitsView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("first commit"), ) @@ -30,13 +30,13 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). Confirm() - assert.CurrentView().Name("commits"). + assert.Views().Current().Name("commits"). Lines( Contains("Revert \"first commit\"").IsSelected(), Contains("first commit"), ) - assert.MainView().Content(Contains("-myfile content")) + assert.Views().Main().Content(Contains("-myfile content")) assert.FileSystemPathNotPresent("myfile") }, }) diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index 4a0c3eafc..7862aaeef 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -18,26 +18,26 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { assert.CommitCount(0) - assert.CurrentView().Name("files") - assert.CurrentView().SelectedLine(Contains("myfile")) + assert.Views().Current().Name("files") + assert.Views().Current().SelectedLine(Contains("myfile")) // stage the file input.PrimaryAction() input.Enter() - assert.CurrentView().Name("stagingSecondary") + assert.Views().Current().Name("stagingSecondary") // we start with both lines having been staged - assert.View("stagingSecondary").Content(Contains("+myfile content")) - assert.View("stagingSecondary").Content(Contains("+with a second line")) - assert.View("staging").Content(DoesNotContain("+myfile content")) - assert.View("staging").Content(DoesNotContain("+with a second line")) + assert.Views().ByName("stagingSecondary").Content(Contains("+myfile content")) + assert.Views().ByName("stagingSecondary").Content(Contains("+with a second line")) + assert.Views().ByName("staging").Content(DoesNotContain("+myfile content")) + assert.Views().ByName("staging").Content(DoesNotContain("+with a second line")) // unstage the selected line input.PrimaryAction() // the line should have been moved to the main view - assert.View("stagingSecondary").Content(DoesNotContain("+myfile content")) - assert.View("stagingSecondary").Content(Contains("+with a second line")) - assert.View("staging").Content(Contains("+myfile content")) - assert.View("staging").Content(DoesNotContain("+with a second line")) + assert.Views().ByName("stagingSecondary").Content(DoesNotContain("+myfile content")) + assert.Views().ByName("stagingSecondary").Content(Contains("+with a second line")) + assert.Views().ByName("staging").Content(Contains("+myfile content")) + assert.Views().ByName("staging").Content(DoesNotContain("+with a second line")) input.Press(keys.Files.CommitChanges) commitMessage := "my commit message" diff --git a/pkg/integration/tests/commit/staged_without_hooks.go b/pkg/integration/tests/commit/staged_without_hooks.go index 95fa72e7e..1f41238a3 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -19,16 +19,16 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(0) // stage the file - assert.CurrentView().Name("files") - assert.CurrentView().SelectedLine(Contains("myfile")) + assert.Views().Current().Name("files") + assert.Views().Current().SelectedLine(Contains("myfile")) input.PrimaryAction() input.Enter() - assert.CurrentView().Name("stagingSecondary") + assert.Views().Current().Name("stagingSecondary") // we start with both lines having been staged - assert.View("stagingSecondary").Content( + assert.Views().ByName("stagingSecondary").Content( Contains("+myfile content").Contains("+with a second line"), ) - assert.View("staging").Content( + assert.Views().ByName("staging").Content( DoesNotContain("+myfile content").DoesNotContain("+with a second line"), ) @@ -36,8 +36,8 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ input.PrimaryAction() // the line should have been moved to the main view - assert.View("stagingSecondary").Content(DoesNotContain("+myfile content").Contains("+with a second line")) - assert.View("staging").Content(Contains("+myfile content").DoesNotContain("+with a second line")) + assert.Views().ByName("stagingSecondary").Content(DoesNotContain("+myfile content").Contains("+with a second line")) + assert.Views().ByName("staging").Content(Contains("+myfile content").DoesNotContain("+with a second line")) input.Press(keys.Files.CommitChangesWithoutHook) @@ -46,7 +46,7 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(1) assert.HeadCommitMessage(Equals("WIP" + commitMessage)) - assert.CurrentView().Name("stagingSecondary") + assert.Views().Current().Name("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 f46c06a87..9b56c9c43 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -20,14 +20,14 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { assert.CommitCount(0) - assert.CurrentView().Name("files").SelectedLine(Contains("myfile")) + assert.Views().Current().Name("files").SelectedLine(Contains("myfile")) input.Enter() - assert.CurrentView().Name("staging") - assert.View("stagingSecondary").Content(DoesNotContain("+myfile content")) + assert.Views().Current().Name("staging") + assert.Views().ByName("stagingSecondary").Content(DoesNotContain("+myfile content")) // stage the first line input.PrimaryAction() - assert.View("staging").Content(DoesNotContain("+myfile content")) - assert.View("stagingSecondary").Content(Contains("+myfile content")) + assert.Views().ByName("staging").Content(DoesNotContain("+myfile content")) + assert.Views().ByName("stagingSecondary").Content(Contains("+myfile content")) input.Press(keys.Files.CommitChanges) diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go index fc3cad569..7fb67aa77 100644 --- a/pkg/integration/tests/custom_commands/basic.go +++ b/pkg/integration/tests/custom_commands/basic.go @@ -31,7 +31,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ input.Press("a") - assert.View("files").Lines( + assert.Views().ByName("files").Lines( Contains("myfile"), ) }, diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index fa6495a93..6778dd7aa 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -75,7 +75,7 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ Confirm() assert.WorkingTreeFileCount(1) - assert.CurrentView().SelectedLine(Contains("my file")) - assert.MainView().Content(Contains(`"BAR"`)) + assert.Views().Current().SelectedLine(Contains("my file")) + assert.Views().Main().Content(Contains(`"BAR"`)) }, }) diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index d9b9fab05..7268a0c25 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -60,7 +60,7 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToFilesView() assert.WorkingTreeFileCount(1) - assert.CurrentView().SelectedLine(Contains("output.txt")) - assert.MainView().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) + assert.Views().Current().SelectedLine(Contains("output.txt")) + assert.Views().Main().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) }, }) 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 d17cb1176..f7177f086 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -55,7 +55,7 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ input.Press("a") assert.InPrompt() - assert.CurrentView(). + assert.Views().Current(). Title(Equals("Which git command do you want to run?")). SelectedLine(Equals("branch")) input.Confirm() diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index 9b77a05bf..ec49a127d 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -73,7 +73,7 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ Confirm() assert.WorkingTreeFileCount(1) - assert.CurrentView().SelectedLine(Contains("myfile")) - assert.MainView().Content(Contains("BAR")) + assert.Views().Current().SelectedLine(Contains("myfile")) + assert.Views().Main().Content(Contains("BAR")) }, }) diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index e0fc214b2..96484b421 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -24,35 +24,35 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.CurrentView().TopLines( + assert.Views().Current().TopLines( Contains("branch-a"), Contains("branch-b"), ) input.Press(keys.Universal.DiffingMenu) input.Menu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() - assert.CurrentView().Name("localBranches") + assert.Views().Current().Name("localBranches") - assert.View("information").Content(Contains("showing output for: git diff branch-a branch-a")) + assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-a")) input.NextItem() - assert.View("information").Content(Contains("showing output for: git diff branch-a branch-b")) - assert.MainView().Content(Contains("+second line")) + assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-b")) + assert.Views().Main().Content(Contains("+second line")) input.Enter() - assert.CurrentView().Name("subCommits") - assert.MainView().Content(Contains("+second line")) - assert.CurrentView().SelectedLine(Contains("update")) + assert.Views().Current().Name("subCommits") + assert.Views().Main().Content(Contains("+second line")) + assert.Views().Current().SelectedLine(Contains("update")) input.Enter() - assert.CurrentView().Name("commitFiles").SelectedLine(Contains("file1")) - assert.MainView().Content(Contains("+second line")) + assert.Views().Current().Name("commitFiles").SelectedLine(Contains("file1")) + assert.Views().Main().Content(Contains("+second line")) input.Press(keys.Universal.Return) input.Press(keys.Universal.Return) - assert.CurrentView().Name("localBranches") + assert.Views().Current().Name("localBranches") input.Press(keys.Universal.DiffingMenu) input.Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - assert.View("information").Content(Contains("showing output for: git diff branch-a branch-b -R")) - assert.MainView().Content(Contains("-second line")) + assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-b -R")) + assert.Views().Main().Content(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 e6dfe5a97..fdcaf0be7 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -23,7 +23,7 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToBranchesView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("branch-a"), Contains("branch-b"), ) @@ -32,21 +32,21 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() - assert.CurrentView().Name("localBranches") + assert.Views().Current().Name("localBranches") - assert.View("information").Content(Contains("showing output for: git diff branch-a branch-a")) + assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-a")) input.NextItem() - assert.View("information").Content(Contains("showing output for: git diff branch-a branch-b")) - assert.MainView().Content(Contains("+second line")) + assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-b")) + assert.Views().Main().Content(Contains("+second line")) input.Enter() - assert.CurrentView().Name("subCommits") - assert.MainView().Content(Contains("+second line")) - assert.CurrentView().SelectedLine(Contains("update")) + assert.Views().Current().Name("subCommits") + assert.Views().Main().Content(Contains("+second line")) + assert.Views().Current().SelectedLine(Contains("update")) input.Enter() - assert.CurrentView().Name("commitFiles") - assert.CurrentView().SelectedLine(Contains("file1")) - assert.MainView().Content(Contains("+second line")) + assert.Views().Current().Name("commitFiles") + assert.Views().Current().SelectedLine(Contains("file1")) + assert.Views().Main().Content(Contains("+second line")) // add the file to the patch input.PrimaryAction() @@ -54,7 +54,7 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Universal.DiffingMenu) input.Menu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() - assert.View("information").Content(DoesNotContain("building patch")) + assert.Views().ByName("information").Content(DoesNotContain("building patch")) input.Press(keys.Universal.CreatePatchOptionsMenu) // adding the regex '$' here to distinguish the menu item from the 'apply patch in reverse' item @@ -62,7 +62,7 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToFilesView() - assert.CurrentView().SelectedLine(Contains("file1")) - assert.MainView().Content(Contains("+second line")) + assert.Views().Current().SelectedLine(Contains("file1")) + assert.Views().Main().Content(Contains("+second line")) }, }) diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index e4db05f18..9095c22e8 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -21,7 +21,7 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToCommitsView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("third commit"), Contains("second commit"), Contains("first commit"), @@ -32,23 +32,23 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ assert.NotInPopup() - assert.View("information").Content(Contains("showing output for: git diff")) + assert.Views().ByName("information").Content(Contains("showing output for: git diff")) input.NextItem() input.NextItem() - assert.CurrentView().SelectedLine(Contains("first commit")) + assert.Views().Current().SelectedLine(Contains("first commit")) - assert.MainView().Content(Contains("-second line\n-third line")) + assert.Views().Main().Content(Contains("-second line\n-third line")) input.Press(keys.Universal.DiffingMenu) input.Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() assert.NotInPopup() - assert.MainView().Content(Contains("+second line\n+third line")) + assert.Views().Main().Content(Contains("+second line\n+third line")) input.Enter() - assert.CurrentView().Name("commitFiles").SelectedLine(Contains("file1")) - assert.MainView().Content(Contains("+second line\n+third line")) + assert.Views().Current().Name("commitFiles").SelectedLine(Contains("file1")) + assert.Views().Main().Content(Contains("+second line\n+third line")) }, }) diff --git a/pkg/integration/tests/file/dir_with_untracked_file.go b/pkg/integration/tests/file/dir_with_untracked_file.go index b85ea273b..344aa7c91 100644 --- a/pkg/integration/tests/file/dir_with_untracked_file.go +++ b/pkg/integration/tests/file/dir_with_untracked_file.go @@ -24,7 +24,7 @@ var DirWithUntrackedFile = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { assert.CommitCount(1) - assert.MainView(). + assert.Views().Main(). Content(DoesNotContain("error: Could not access")). // we show baz because it's a modified file but we don't show bar because it's untracked // (though it would be cool if we could show that too) diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index e965385ec..12324e7c1 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -82,7 +82,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ discardOneByOne := func(files []statusFile) { for _, file := range files { - assert.CurrentView().SelectedLine(Contains(file.status + " " + file.label)) + assert.Views().Current().SelectedLine(Contains(file.status + " " + file.label)) input.Press(keys.Universal.Remove) input.Menu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() } diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index f1ea39d04..67a90ff6f 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -46,7 +46,7 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ assert.HeadCommitMessage(Contains(mergeCommitMessage)) // assuring the post-merge file shows up in the merge commit. - assert.MainView(). + assert.Views().Main(). Content(Contains(postMergeFilename)). Content(Contains("++" + postMergeFileContent)) }, diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go index 3c4c07a4d..170bcf364 100644 --- a/pkg/integration/tests/interactive_rebase/one.go +++ b/pkg/integration/tests/interactive_rebase/one.go @@ -16,7 +16,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToCommitsView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("commit 05"), Contains("commit 04"), Contains("commit 03"), @@ -27,7 +27,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ input.NavigateToListItem(Contains("commit 02")) input.Press(keys.Universal.Edit) - assert.CurrentView().Lines( + assert.Views().Current().Lines( MatchesRegexp("pick.*commit 05"), MatchesRegexp("pick.*commit 04"), MatchesRegexp("pick.*commit 03"), @@ -37,7 +37,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ input.PreviousItem() input.Press(keys.Commits.MarkCommitAsFixup) - assert.CurrentView().Lines( + assert.Views().Current().Lines( MatchesRegexp("pick.*commit 05"), MatchesRegexp("pick.*commit 04"), MatchesRegexp("fixup.*commit 03"), @@ -47,7 +47,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ input.PreviousItem() input.Press(keys.Universal.Remove) - assert.CurrentView().Lines( + assert.Views().Current().Lines( MatchesRegexp("pick.*commit 05"), MatchesRegexp("drop.*commit 04"), MatchesRegexp("fixup.*commit 03"), @@ -58,7 +58,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ input.PreviousItem() input.Press(keys.Commits.SquashDown) - assert.CurrentView().Lines( + assert.Views().Current().Lines( MatchesRegexp("squash.*commit 05"), MatchesRegexp("drop.*commit 04"), MatchesRegexp("fixup.*commit 03"), @@ -68,7 +68,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ input.ContinueRebase() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Contains("commit 02"), Contains("commit 01"), ) diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index 99036b7f6..443f64a14 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -21,7 +21,7 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.SwitchToStashView() - assert.CurrentView().Lines( + assert.Views().Current().Lines( Equals("On master: bar"), Equals("On master: foo"), ) @@ -30,6 +30,6 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ input.Prompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() - assert.CurrentView().SelectedLine(Equals("On master: foo baz")) + assert.Views().Current().SelectedLine(Equals("On master: foo baz")) }, }) From 09e80e5f2a56e5d13262e6d01c68cb4054bad6f4 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 15:22:31 +1100 Subject: [PATCH 06/20] better namespacing for assertions --- pkg/integration/components/alert_asserter.go | 2 +- pkg/integration/components/assert.go | 214 ++---------------- .../components/assertion_helper.go | 40 ++++ .../commit_message_panel_asserter.go | 2 +- .../components/confirmation_asserter.go | 2 +- pkg/integration/components/file_system.go | 26 +++ pkg/integration/components/input.go | 88 +++++-- pkg/integration/components/menu_asserter.go | 2 +- pkg/integration/components/model.go | 72 ++++++ pkg/integration/components/prompt_asserter.go | 2 +- pkg/integration/components/test_test.go | 4 +- .../components/{view_asserter.go => views.go} | 54 ++++- pkg/integration/tests/bisect/basic.go | 2 +- .../tests/bisect/from_other_branch.go | 2 +- pkg/integration/tests/branch/suggestions.go | 2 +- .../cherry_pick/cherry_pick_conflicts.go | 2 +- pkg/integration/tests/commit/commit.go | 6 +- .../tests/commit/commit_multiline.go | 6 +- pkg/integration/tests/commit/new_branch.go | 4 +- pkg/integration/tests/commit/revert.go | 4 +- pkg/integration/tests/commit/staged.go | 8 +- .../tests/commit/staged_without_hooks.go | 6 +- pkg/integration/tests/commit/unstaged.go | 8 +- .../tests/config/remote_named_star.go | 2 +- .../tests/custom_commands/basic.go | 2 +- .../tests/custom_commands/form_prompts.go | 4 +- .../custom_commands/menu_from_command.go | 4 +- .../menu_from_commands_output.go | 13 +- .../tests/custom_commands/multiple_prompts.go | 4 +- pkg/integration/tests/diff/diff_commits.go | 3 - .../tests/file/dir_with_untracked_file.go | 2 +- pkg/integration/tests/file/discard_changes.go | 4 +- .../tests/interactive_rebase/amend_merge.go | 8 +- pkg/integration/tests/misc/confirm_on_quit.go | 2 +- pkg/integration/tests/stash/stash.go | 8 +- .../stash/stash_including_untracked_files.go | 8 +- 36 files changed, 328 insertions(+), 294 deletions(-) create mode 100644 pkg/integration/components/assertion_helper.go create mode 100644 pkg/integration/components/file_system.go create mode 100644 pkg/integration/components/model.go rename pkg/integration/components/{view_asserter.go => views.go} (70%) diff --git a/pkg/integration/components/alert_asserter.go b/pkg/integration/components/alert_asserter.go index 9dc2d32ab..8ca027b59 100644 --- a/pkg/integration/components/alert_asserter.go +++ b/pkg/integration/components/alert_asserter.go @@ -7,7 +7,7 @@ type AlertAsserter struct { hasCheckedContent bool } -func (self *AlertAsserter) getViewAsserter() *ViewAsserter { +func (self *AlertAsserter) getViewAsserter() *Views { return self.assert.Views().ByName("confirmation") } diff --git a/pkg/integration/components/assert.go b/pkg/integration/components/assert.go index b4be669c5..42ef90d6f 100644 --- a/pkg/integration/components/assert.go +++ b/pkg/integration/components/assert.go @@ -1,12 +1,6 @@ package components import ( - "fmt" - "os" - "time" - - "github.com/jesseduffield/gocui" - "github.com/jesseduffield/lazygit/pkg/gui/types" integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" ) @@ -14,212 +8,30 @@ import ( type Assert struct { gui integrationTypes.GuiDriver + *assertionHelper } func NewAssert(gui integrationTypes.GuiDriver) *Assert { return &Assert{gui: gui} } -func (self *Assert) WorkingTreeFileCount(expectedCount int) { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().Files) - - return actualCount == expectedCount, fmt.Sprintf( - "Expected %d changed working tree files, but got %d", - expectedCount, actualCount, - ) - }) -} - -func (self *Assert) CommitCount(expectedCount int) { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().Commits) - - return actualCount == expectedCount, fmt.Sprintf( - "Expected %d commits present, but got %d", - expectedCount, actualCount, - ) - }) -} - -func (self *Assert) StashCount(expectedCount int) { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().StashEntries) - - return actualCount == expectedCount, fmt.Sprintf( - "Expected %d stash entries, but got %d", - expectedCount, actualCount, - ) - }) -} - -func (self *Assert) AtLeastOneCommit() { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().Commits) - - return actualCount > 0, "Expected at least one commit present" - }) -} - -func (self *Assert) HeadCommitMessage(matcher *matcher) { - self.assertWithRetries(func() (bool, string) { - return len(self.gui.Model().Commits) > 0, "Expected at least one commit to be present" - }) - - self.matchString(matcher, "Unexpected commit message.", - func() string { - return self.gui.Model().Commits[0].Name - }, - ) -} - -func (self *Assert) CurrentWindowName(expectedWindowName string) { - self.assertWithRetries(func() (bool, string) { - actual := self.gui.CurrentContext().GetView().Name() - return actual == expectedWindowName, fmt.Sprintf("Expected current window name to be '%s', but got '%s'", expectedWindowName, actual) - }) -} - -func (self *Assert) CurrentBranchName(expectedViewName string) { - self.assertWithRetries(func() (bool, string) { - actual := self.gui.CheckedOutRef().Name - return actual == expectedViewName, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expectedViewName, actual) - }) -} - -func (self *Assert) InListContext() { - self.assertWithRetries(func() (bool, string) { - currentContext := self.gui.CurrentContext() - _, ok := currentContext.(types.IListContext) - return ok, fmt.Sprintf("Expected current context to be a list context, but got %s", currentContext.GetKey()) - }) -} - -func (self *Assert) InPrompt() { - self.assertWithRetries(func() (bool, string) { - currentView := self.gui.CurrentContext().GetView() - return currentView.Name() == "confirmation" && currentView.Editable, "Expected prompt popup to be focused" - }) -} - -func (self *Assert) InConfirm() { - self.assertWithRetries(func() (bool, string) { - currentView := self.gui.CurrentContext().GetView() - return currentView.Name() == "confirmation" && !currentView.Editable, "Expected confirmation popup to be focused" - }) -} - -func (self *Assert) InAlert() { - // basically the same thing as a confirmation popup with the current implementation - self.assertWithRetries(func() (bool, string) { - currentView := self.gui.CurrentContext().GetView() - return currentView.Name() == "confirmation" && !currentView.Editable, "Expected alert popup to be focused" - }) -} - -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" - }) -} - -func (self *Assert) NotInPopup() { - self.assertWithRetries(func() (bool, string) { - currentViewName := self.gui.CurrentContext().GetView().Name() - return currentViewName != "menu" && currentViewName != "confirmation" && currentViewName != "commitMessage", "Expected popup not to be focused" - }) -} - -func (self *Assert) matchString(matcher *matcher, context string, getValue func() string) { - self.assertWithRetries(func() (bool, string) { - value := getValue() - return matcher.context(context).test(value) - }) -} - -func (self *Assert) assertWithRetries(test func() (bool, string)) { - waitTimes := []int{0, 1, 1, 1, 1, 1, 5, 10, 20, 40, 100, 200, 500, 1000, 2000, 4000} - - var message string - for _, waitTime := range waitTimes { - time.Sleep(time.Duration(waitTime) * time.Millisecond) - - var ok bool - ok, message = test() - if ok { - return - } - } - - self.Fail(message) -} - -// for when you just want to fail the test yourself -func (self *Assert) Fail(message string) { - self.gui.Fail(message) -} - -// This does _not_ check the files panel, it actually checks the filesystem -func (self *Assert) FileSystemPathPresent(path string) { - self.assertWithRetries(func() (bool, string) { - _, err := os.Stat(path) - return err == nil, fmt.Sprintf("Expected path '%s' to exist, but it does not", path) - }) -} - -// This does _not_ check the files panel, it actually checks the filesystem -func (self *Assert) FileSystemPathNotPresent(path string) { - self.assertWithRetries(func() (bool, string) { - _, err := os.Stat(path) - return os.IsNotExist(err), fmt.Sprintf("Expected path '%s' to not exist, but it does", path) - }) -} - +// for making assertions on lazygit views func (self *Assert) Views() *ViewAsserterGetter { - return &ViewAsserterGetter{ - assert: self, - } + return &ViewAsserterGetter{assert: self} } -type ViewAsserterGetter struct { - assert *Assert +// for making assertions on the lazygit model +func (self *Assert) Model() *Model { + return &Model{assertionHelper: self.assertionHelper, gui: self.gui} } -func (self *ViewAsserterGetter) Current() *ViewAsserter { - return &ViewAsserter{ - context: "current view", - getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() }, - assert: self.assert, - } +// for making assertions on the file system +func (self *Assert) FileSystem() *FileSystem { + return &FileSystem{assertionHelper: self.assertionHelper} } -func (self *ViewAsserterGetter) Main() *ViewAsserter { - return &ViewAsserter{ - context: "main view", - getView: func() *gocui.View { return self.assert.gui.MainView() }, - assert: self.assert, - } -} - -func (self *ViewAsserterGetter) Secondary() *ViewAsserter { - return &ViewAsserter{ - context: "secondary view", - getView: func() *gocui.View { return self.assert.gui.SecondaryView() }, - assert: self.assert, - } -} - -func (self *ViewAsserterGetter) ByName(viewName string) *ViewAsserter { - return &ViewAsserter{ - context: fmt.Sprintf("%s view", viewName), - getView: func() *gocui.View { return self.assert.gui.View(viewName) }, - assert: self.assert, - } +// for when you just want to fail the test yourself. +// This runs callbacks to ensure we render the error after closing the gui. +func (self *Assert) Fail(message string) { + self.assertionHelper.fail(message) } diff --git a/pkg/integration/components/assertion_helper.go b/pkg/integration/components/assertion_helper.go new file mode 100644 index 000000000..70f2ff182 --- /dev/null +++ b/pkg/integration/components/assertion_helper.go @@ -0,0 +1,40 @@ +package components + +import ( + "time" + + integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" +) + +type assertionHelper struct { + gui integrationTypes.GuiDriver +} + +// milliseconds we'll wait when an assertion fails. +var retryWaitTimes = []int{0, 1, 1, 1, 1, 1, 5, 10, 20, 40, 100, 200, 500, 1000, 2000, 4000} + +func (self *assertionHelper) matchString(matcher *matcher, context string, getValue func() string) { + self.assertWithRetries(func() (bool, string) { + value := getValue() + return matcher.context(context).test(value) + }) +} + +func (self *assertionHelper) assertWithRetries(test func() (bool, string)) { + var message string + for _, waitTime := range retryWaitTimes { + time.Sleep(time.Duration(waitTime) * time.Millisecond) + + var ok bool + ok, message = test() + if ok { + return + } + } + + self.fail(message) +} + +func (self *assertionHelper) fail(message string) { + self.gui.Fail(message) +} diff --git a/pkg/integration/components/commit_message_panel_asserter.go b/pkg/integration/components/commit_message_panel_asserter.go index 6ffb6b80c..3a534bd2d 100644 --- a/pkg/integration/components/commit_message_panel_asserter.go +++ b/pkg/integration/components/commit_message_panel_asserter.go @@ -5,7 +5,7 @@ type CommitMessagePanelAsserter struct { input *Input } -func (self *CommitMessagePanelAsserter) getViewAsserter() *ViewAsserter { +func (self *CommitMessagePanelAsserter) getViewAsserter() *Views { return self.assert.Views().ByName("commitMessage") } diff --git a/pkg/integration/components/confirmation_asserter.go b/pkg/integration/components/confirmation_asserter.go index 371e46028..9cf4d653d 100644 --- a/pkg/integration/components/confirmation_asserter.go +++ b/pkg/integration/components/confirmation_asserter.go @@ -7,7 +7,7 @@ type ConfirmationAsserter struct { hasCheckedContent bool } -func (self *ConfirmationAsserter) getViewAsserter() *ViewAsserter { +func (self *ConfirmationAsserter) getViewAsserter() *Views { return self.assert.Views().ByName("confirmation") } diff --git a/pkg/integration/components/file_system.go b/pkg/integration/components/file_system.go new file mode 100644 index 000000000..040234e77 --- /dev/null +++ b/pkg/integration/components/file_system.go @@ -0,0 +1,26 @@ +package components + +import ( + "fmt" + "os" +) + +type FileSystem struct { + *assertionHelper +} + +// This does _not_ check the files panel, it actually checks the filesystem +func (self *FileSystem) PathPresent(path string) { + self.assertWithRetries(func() (bool, string) { + _, err := os.Stat(path) + return err == nil, fmt.Sprintf("Expected path '%s' to exist, but it does not", path) + }) +} + +// This does _not_ check the files panel, it actually checks the filesystem +func (self *FileSystem) PathNotPresent(path string) { + self.assertWithRetries(func() (bool, string) { + _, err := os.Stat(path) + return os.IsNotExist(err), fmt.Sprintf("Expected path '%s' to not exist, but it does", path) + }) +} diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index 014a74d5d..2f1ed18c5 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -11,18 +11,20 @@ import ( ) type Input struct { - gui integrationTypes.GuiDriver - keys config.KeybindingConfig - assert *Assert + gui integrationTypes.GuiDriver + keys config.KeybindingConfig + assert *Assert + *assertionHelper pushKeyDelay int } func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, assert *Assert, pushKeyDelay int) *Input { return &Input{ - gui: gui, - keys: keys, - assert: assert, - pushKeyDelay: pushKeyDelay, + gui: gui, + keys: keys, + assert: assert, + pushKeyDelay: pushKeyDelay, + assertionHelper: assert.assertionHelper, } } @@ -42,7 +44,7 @@ func (self *Input) press(keyStr string) { func (self *Input) SwitchToStatusWindow() { self.press(self.keys.Universal.JumpToBlock[0]) - self.assert.CurrentWindowName("status") + self.currentWindowName("status") } // switch to status window and assert that the status view is on top @@ -53,7 +55,7 @@ func (self *Input) SwitchToStatusView() { func (self *Input) SwitchToFilesWindow() { self.press(self.keys.Universal.JumpToBlock[1]) - self.assert.CurrentWindowName("files") + self.currentWindowName("files") } // switch to files window and assert that the files view is on top @@ -64,7 +66,7 @@ func (self *Input) SwitchToFilesView() { func (self *Input) SwitchToBranchesWindow() { self.press(self.keys.Universal.JumpToBlock[2]) - self.assert.CurrentWindowName("localBranches") + self.currentWindowName("localBranches") } // switch to branches window and assert that the branches view is on top @@ -75,7 +77,7 @@ func (self *Input) SwitchToBranchesView() { func (self *Input) SwitchToCommitsWindow() { self.press(self.keys.Universal.JumpToBlock[3]) - self.assert.CurrentWindowName("commits") + self.currentWindowName("commits") } // switch to commits window and assert that the commits view is on top @@ -86,7 +88,7 @@ func (self *Input) SwitchToCommitsView() { func (self *Input) SwitchToStashWindow() { self.press(self.keys.Universal.JumpToBlock[4]) - self.assert.CurrentWindowName("stash") + self.currentWindowName("stash") } // switch to stash window and assert that the stash view is on top @@ -166,7 +168,7 @@ func (self *Input) Log(message string) { // 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) NavigateToListItem(matcher *matcher) { - self.assert.InListContext() + self.inListContext() currentContext := self.gui.CurrentContext().(types.IListContext) @@ -215,32 +217,82 @@ func (self *Input) NavigateToListItem(matcher *matcher) { } } +func (self *Input) inListContext() { + self.assertWithRetries(func() (bool, string) { + currentContext := self.gui.CurrentContext() + _, ok := currentContext.(types.IListContext) + return ok, fmt.Sprintf("Expected current context to be a list context, but got %s", currentContext.GetKey()) + }) +} + func (self *Input) Confirmation() *ConfirmationAsserter { - self.assert.InConfirm() + self.inConfirm() return &ConfirmationAsserter{assert: self.assert, input: self} } +func (self *Input) inConfirm() { + self.assertWithRetries(func() (bool, string) { + currentView := self.gui.CurrentContext().GetView() + return currentView.Name() == "confirmation" && !currentView.Editable, "Expected confirmation popup to be focused" + }) +} + func (self *Input) Prompt() *PromptAsserter { - self.assert.InPrompt() + self.inPrompt() return &PromptAsserter{assert: self.assert, input: self} } +func (self *Input) inPrompt() { + self.assertWithRetries(func() (bool, string) { + currentView := self.gui.CurrentContext().GetView() + return currentView.Name() == "confirmation" && currentView.Editable, "Expected prompt popup to be focused" + }) +} + func (self *Input) Alert() *AlertAsserter { - self.assert.InAlert() + self.inAlert() return &AlertAsserter{assert: self.assert, input: self} } +func (self *Input) inAlert() { + // basically the same thing as a confirmation popup with the current implementation + self.assertWithRetries(func() (bool, string) { + currentView := self.gui.CurrentContext().GetView() + return currentView.Name() == "confirmation" && !currentView.Editable, "Expected alert popup to be focused" + }) +} + func (self *Input) Menu() *MenuAsserter { - self.assert.InMenu() + self.inMenu() return &MenuAsserter{assert: self.assert, input: self} } +func (self *Input) inMenu() { + self.assertWithRetries(func() (bool, string) { + return self.gui.CurrentContext().GetView().Name() == "menu", "Expected popup menu to be focused" + }) +} + func (self *Input) CommitMessagePanel() *CommitMessagePanelAsserter { - self.assert.InCommitMessagePanel() + self.inCommitMessagePanel() return &CommitMessagePanelAsserter{assert: self.assert, input: self} } + +func (self *Input) inCommitMessagePanel() { + self.assertWithRetries(func() (bool, string) { + currentView := self.gui.CurrentContext().GetView() + return currentView.Name() == "commitMessage", "Expected commit message panel to be focused" + }) +} + +func (self *Input) currentWindowName(expectedWindowName string) { + self.assertWithRetries(func() (bool, string) { + actual := self.gui.CurrentContext().GetView().Name() + return actual == expectedWindowName, fmt.Sprintf("Expected current window name to be '%s', but got '%s'", expectedWindowName, actual) + }) +} diff --git a/pkg/integration/components/menu_asserter.go b/pkg/integration/components/menu_asserter.go index ab2256320..e302c235b 100644 --- a/pkg/integration/components/menu_asserter.go +++ b/pkg/integration/components/menu_asserter.go @@ -6,7 +6,7 @@ type MenuAsserter struct { hasCheckedTitle bool } -func (self *MenuAsserter) getViewAsserter() *ViewAsserter { +func (self *MenuAsserter) getViewAsserter() *Views { return self.assert.Views().ByName("menu") } diff --git a/pkg/integration/components/model.go b/pkg/integration/components/model.go new file mode 100644 index 000000000..83d2e97e8 --- /dev/null +++ b/pkg/integration/components/model.go @@ -0,0 +1,72 @@ +package components + +import ( + "fmt" + + integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" +) + +type Model struct { + *assertionHelper + gui integrationTypes.GuiDriver +} + +func (self *Model) WorkingTreeFileCount(expectedCount int) { + self.assertWithRetries(func() (bool, string) { + actualCount := len(self.gui.Model().Files) + + return actualCount == expectedCount, fmt.Sprintf( + "Expected %d changed working tree files, but got %d", + expectedCount, actualCount, + ) + }) +} + +func (self *Model) CommitCount(expectedCount int) { + self.assertWithRetries(func() (bool, string) { + actualCount := len(self.gui.Model().Commits) + + return actualCount == expectedCount, fmt.Sprintf( + "Expected %d commits present, but got %d", + expectedCount, actualCount, + ) + }) +} + +func (self *Model) StashCount(expectedCount int) { + self.assertWithRetries(func() (bool, string) { + actualCount := len(self.gui.Model().StashEntries) + + return actualCount == expectedCount, fmt.Sprintf( + "Expected %d stash entries, but got %d", + expectedCount, actualCount, + ) + }) +} + +func (self *Model) AtLeastOneCommit() { + self.assertWithRetries(func() (bool, string) { + actualCount := len(self.gui.Model().Commits) + + return actualCount > 0, "Expected at least one commit present" + }) +} + +func (self *Model) HeadCommitMessage(matcher *matcher) { + self.assertWithRetries(func() (bool, string) { + return len(self.gui.Model().Commits) > 0, "Expected at least one commit to be present" + }) + + self.matchString(matcher, "Unexpected commit message.", + func() string { + return self.gui.Model().Commits[0].Name + }, + ) +} + +func (self *Model) CurrentBranchName(expectedViewName string) { + self.assertWithRetries(func() (bool, string) { + actual := self.gui.CheckedOutRef().Name + return actual == expectedViewName, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expectedViewName, actual) + }) +} diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go index 079cc4d3f..b03ee85b7 100644 --- a/pkg/integration/components/prompt_asserter.go +++ b/pkg/integration/components/prompt_asserter.go @@ -6,7 +6,7 @@ type PromptAsserter struct { hasCheckedTitle bool } -func (self *PromptAsserter) getViewAsserter() *ViewAsserter { +func (self *PromptAsserter) getViewAsserter() *Views { return self.assert.Views().ByName("confirmation") } diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index dbab22883..eb901a402 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -66,7 +66,7 @@ func TestAssertionFailure(t *testing.T) { Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.Press("a") input.Press("b") - assert.CommitCount(2) + assert.Model().CommitCount(2) }, }) driver := &fakeGuiDriver{} @@ -93,7 +93,7 @@ func TestSuccess(t *testing.T) { Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { input.Press("a") input.Press("b") - assert.CommitCount(0) + assert.Model().CommitCount(0) }, }) driver := &fakeGuiDriver{} diff --git a/pkg/integration/components/view_asserter.go b/pkg/integration/components/views.go similarity index 70% rename from pkg/integration/components/view_asserter.go rename to pkg/integration/components/views.go index 73f315993..624d1f66e 100644 --- a/pkg/integration/components/view_asserter.go +++ b/pkg/integration/components/views.go @@ -6,7 +6,7 @@ import ( "github.com/jesseduffield/gocui" ) -type ViewAsserter struct { +type Views struct { // context is prepended to any error messages e.g. 'context: "current view"' context string getView func() *gocui.View @@ -15,7 +15,7 @@ type ViewAsserter struct { // asserts that the view has the expected name. This is typically used in tandem with the CurrentView method i.e.; // assert.CurrentView().Name("commits") to assert that the current view is the commits view. -func (self *ViewAsserter) Name(expected string) *ViewAsserter { +func (self *Views) Name(expected string) *Views { self.assert.assertWithRetries(func() (bool, string) { actual := self.getView().Name() return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual) @@ -25,7 +25,7 @@ func (self *ViewAsserter) Name(expected string) *ViewAsserter { } // asserts that the view has the expected title -func (self *ViewAsserter) Title(expected *matcher) *ViewAsserter { +func (self *Views) Title(expected *matcher) *Views { self.assert.assertWithRetries(func() (bool, string) { actual := self.getView().Title return expected.context(fmt.Sprintf("%s title", self.context)).test(actual) @@ -38,7 +38,7 @@ func (self *ViewAsserter) Title(expected *matcher) *ViewAsserter { // are passed, we only check the first three lines of the view. // This method is convenient when you have a list of commits but you only want to // assert on the first couple of commits. -func (self *ViewAsserter) TopLines(matchers ...*matcher) *ViewAsserter { +func (self *Views) TopLines(matchers ...*matcher) *Views { self.assert.assertWithRetries(func() (bool, string) { lines := self.getView().BufferLines() return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines)) @@ -49,7 +49,7 @@ func (self *ViewAsserter) TopLines(matchers ...*matcher) *ViewAsserter { // 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. -func (self *ViewAsserter) Lines(matchers ...*matcher) *ViewAsserter { +func (self *Views) Lines(matchers ...*matcher) *Views { self.assert.assertWithRetries(func() (bool, string) { lines := self.getView().BufferLines() return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines)) @@ -58,7 +58,7 @@ func (self *ViewAsserter) Lines(matchers ...*matcher) *ViewAsserter { return self.assertLines(matchers...) } -func (self *ViewAsserter) assertLines(matchers ...*matcher) *ViewAsserter { +func (self *Views) assertLines(matchers ...*matcher) *Views { view := self.getView() for i, matcher := range matchers { @@ -82,7 +82,7 @@ func (self *ViewAsserter) assertLines(matchers ...*matcher) *ViewAsserter { } // asserts on the content of the view i.e. the stuff within the view's frame. -func (self *ViewAsserter) Content(matcher *matcher) *ViewAsserter { +func (self *Views) Content(matcher *matcher) *Views { self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), func() string { return self.getView().Buffer() @@ -93,7 +93,7 @@ func (self *ViewAsserter) Content(matcher *matcher) *ViewAsserter { } // asserts on the selected line of the view -func (self *ViewAsserter) SelectedLine(matcher *matcher) *ViewAsserter { +func (self *Views) SelectedLine(matcher *matcher) *Views { self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context), func() string { return self.getView().SelectedLine() @@ -104,7 +104,7 @@ func (self *ViewAsserter) SelectedLine(matcher *matcher) *ViewAsserter { } // asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view. -func (self *ViewAsserter) SelectedLineIdx(expected int) *ViewAsserter { +func (self *Views) SelectedLineIdx(expected int) *Views { self.assert.assertWithRetries(func() (bool, string) { actual := self.getView().SelectedLineIdx() return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual) @@ -112,3 +112,39 @@ func (self *ViewAsserter) SelectedLineIdx(expected int) *ViewAsserter { return self } + +type ViewAsserterGetter struct { + assert *Assert +} + +func (self *ViewAsserterGetter) Current() *Views { + return &Views{ + context: "current view", + getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() }, + assert: self.assert, + } +} + +func (self *ViewAsserterGetter) Main() *Views { + return &Views{ + context: "main view", + getView: func() *gocui.View { return self.assert.gui.MainView() }, + assert: self.assert, + } +} + +func (self *ViewAsserterGetter) Secondary() *Views { + return &Views{ + context: "secondary view", + getView: func() *gocui.View { return self.assert.gui.SecondaryView() }, + assert: self.assert, + } +} + +func (self *ViewAsserterGetter) ByName(viewName string) *Views { + return &Views{ + context: fmt.Sprintf("%s view", viewName), + getView: func() *gocui.View { return self.assert.gui.View(viewName) }, + assert: self.assert, + } +} diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index 7e2a21a61..dfe2b6aaa 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -30,7 +30,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ input.Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() } - assert.AtLeastOneCommit() + assert.Model().AtLeastOneCommit() input.SwitchToCommitsView() diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 255b39542..0caab5d67 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -26,7 +26,7 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ ) { assert.Views().ByName("information").Content(Contains("bisecting")) - assert.AtLeastOneCommit() + assert.Model().AtLeastOneCommit() input.SwitchToCommitsView() diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index f9399296d..b33a78721 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -34,6 +34,6 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ SelectFirstSuggestion(). Confirm() - assert.CurrentBranchName("branch-to-checkout") + assert.Model().CurrentBranchName("branch-to-checkout") }, }) diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index b0be4b48e..b078f7164 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -70,7 +70,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Confirm() assert.Views().Current().Name("files") - assert.WorkingTreeFileCount(0) + assert.Model().WorkingTreeFileCount(0) input.SwitchToCommitsView() diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index cda9f63e0..93ccf5b53 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -15,7 +15,7 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("myfile2", "myfile2 content") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(0) + assert.Model().CommitCount(0) input.PrimaryAction() input.NextItem() @@ -26,7 +26,7 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ input.CommitMessagePanel().Type(commitMessage).Confirm() - assert.CommitCount(1) - assert.HeadCommitMessage(Equals(commitMessage)) + assert.Model().CommitCount(1) + assert.Model().HeadCommitMessage(Equals(commitMessage)) }, }) diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index eb0723c39..3beeff344 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -14,15 +14,15 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("myfile", "myfile content") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(0) + assert.Model().CommitCount(0) input.PrimaryAction() input.Press(keys.Files.CommitChanges) input.CommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() - assert.CommitCount(1) - assert.HeadCommitMessage(Equals("first line")) + assert.Model().CommitCount(1) + assert.Model().HeadCommitMessage(Equals("first line")) input.SwitchToCommitsView() assert.Views().Main().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index a4001df8d..c02ffb9a9 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -17,7 +17,7 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("commit 3") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(3) + assert.Model().CommitCount(3) input.SwitchToCommitsView() assert.Views().Current().Lines( @@ -32,7 +32,7 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ branchName := "my-branch-name" input.Prompt().Title(Equals("New Branch Name")).Type(branchName).Confirm() - assert.CurrentBranchName(branchName) + assert.Model().CurrentBranchName(branchName) assert.Views().ByName("commits").Lines( Contains("commit 2"), diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index 5ce7ac12b..ca1a94be5 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -16,7 +16,7 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ shell.Commit("first commit") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(1) + assert.Model().CommitCount(1) input.SwitchToCommitsView() @@ -37,6 +37,6 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ ) assert.Views().Main().Content(Contains("-myfile content")) - assert.FileSystemPathNotPresent("myfile") + assert.FileSystem().PathNotPresent("myfile") }, }) diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index 7862aaeef..ffcd7dd9b 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -16,7 +16,7 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile2", "myfile2 content") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(0) + assert.Model().CommitCount(0) assert.Views().Current().Name("files") assert.Views().Current().SelectedLine(Contains("myfile")) @@ -44,9 +44,9 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ input.Type(commitMessage) input.Confirm() - assert.CommitCount(1) - assert.HeadCommitMessage(Equals(commitMessage)) - assert.CurrentWindowName("stagingSecondary") + assert.Model().CommitCount(1) + assert.Model().HeadCommitMessage(Equals(commitMessage)) + assert.Views().Current().Name("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 1f41238a3..9d1dcb97d 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -16,7 +16,7 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile2", "myfile2 content") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(0) + assert.Model().CommitCount(0) // stage the file assert.Views().Current().Name("files") @@ -44,8 +44,8 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ commitMessage := ": my commit message" input.CommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() - assert.CommitCount(1) - assert.HeadCommitMessage(Equals("WIP" + commitMessage)) + assert.Model().CommitCount(1) + assert.Model().HeadCommitMessage(Equals("WIP" + commitMessage)) assert.Views().Current().Name("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 9b56c9c43..e8c8126e0 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -18,7 +18,7 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile2", "myfile2 content") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(0) + assert.Model().CommitCount(0) assert.Views().Current().Name("files").SelectedLine(Contains("myfile")) input.Enter() @@ -34,9 +34,9 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ commitMessage := "my commit message" input.CommitMessagePanel().Type(commitMessage).Confirm() - assert.CommitCount(1) - assert.HeadCommitMessage(Equals(commitMessage)) - assert.CurrentWindowName("staging") + assert.Model().CommitCount(1) + assert.Model().HeadCommitMessage(Equals(commitMessage)) + assert.Views().Current().Name("staging") // TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed) }, diff --git a/pkg/integration/tests/config/remote_named_star.go b/pkg/integration/tests/config/remote_named_star.go index fd28dea7b..589394061 100644 --- a/pkg/integration/tests/config/remote_named_star.go +++ b/pkg/integration/tests/config/remote_named_star.go @@ -22,6 +22,6 @@ var RemoteNamedStar = NewIntegrationTest(NewIntegrationTestArgs{ keys config.KeybindingConfig, ) { // here we're just asserting that we haven't panicked upon starting lazygit - assert.AtLeastOneCommit() + assert.Model().AtLeastOneCommit() }, }) diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go index 7fb67aa77..bd7b1519b 100644 --- a/pkg/integration/tests/custom_commands/basic.go +++ b/pkg/integration/tests/custom_commands/basic.go @@ -27,7 +27,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - assert.WorkingTreeFileCount(0) + assert.Model().WorkingTreeFileCount(0) input.Press("a") diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index 6778dd7aa..cc854d524 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -61,7 +61,7 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - assert.WorkingTreeFileCount(0) + assert.Model().WorkingTreeFileCount(0) input.Press("a") @@ -74,7 +74,7 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - assert.WorkingTreeFileCount(1) + assert.Model().WorkingTreeFileCount(1) assert.Views().Current().SelectedLine(Contains("my file")) assert.Views().Main().Content(Contains(`"BAR"`)) }, diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index 7268a0c25..a89b4e90a 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -48,7 +48,7 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - assert.WorkingTreeFileCount(0) + assert.Model().WorkingTreeFileCount(0) input.SwitchToBranchesView() input.Press("a") @@ -59,7 +59,7 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToFilesView() - assert.WorkingTreeFileCount(1) + assert.Model().WorkingTreeFileCount(1) assert.Views().Current().SelectedLine(Contains("output.txt")) assert.Views().Main().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) }, 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 f7177f086..e17f38cdd 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -47,21 +47,20 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - assert.CurrentBranchName("feature/bar") + assert.Model().CurrentBranchName("feature/bar") - assert.WorkingTreeFileCount(0) + assert.Model().WorkingTreeFileCount(0) input.SwitchToBranchesView() input.Press("a") - assert.InPrompt() - assert.Views().Current(). + input.Prompt(). Title(Equals("Which git command do you want to run?")). - SelectedLine(Equals("branch")) - input.Confirm() + InitialText(Equals("branch")). + Confirm() input.Menu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() - assert.CurrentBranchName("master") + assert.Model().CurrentBranchName("master") }, }) diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index ec49a127d..c3f040e27 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -59,7 +59,7 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - assert.WorkingTreeFileCount(0) + assert.Model().WorkingTreeFileCount(0) input.Press("a") @@ -72,7 +72,7 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - assert.WorkingTreeFileCount(1) + assert.Model().WorkingTreeFileCount(1) assert.Views().Current().SelectedLine(Contains("myfile")) assert.Views().Main().Content(Contains("BAR")) }, diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index 9095c22e8..d05272e07 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -30,8 +30,6 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Universal.DiffingMenu) input.Menu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() - assert.NotInPopup() - assert.Views().ByName("information").Content(Contains("showing output for: git diff")) input.NextItem() @@ -42,7 +40,6 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ input.Press(keys.Universal.DiffingMenu) input.Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - assert.NotInPopup() assert.Views().Main().Content(Contains("+second line\n+third line")) diff --git a/pkg/integration/tests/file/dir_with_untracked_file.go b/pkg/integration/tests/file/dir_with_untracked_file.go index 344aa7c91..bfd40f2ea 100644 --- a/pkg/integration/tests/file/dir_with_untracked_file.go +++ b/pkg/integration/tests/file/dir_with_untracked_file.go @@ -22,7 +22,7 @@ var DirWithUntrackedFile = NewIntegrationTest(NewIntegrationTestArgs{ shell.UpdateFile("dir/file", "baz") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(1) + assert.Model().CommitCount(1) assert.Views().Main(). Content(DoesNotContain("error: Could not access")). diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index 12324e7c1..cb650f34d 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -72,7 +72,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(3) + assert.Model().CommitCount(3) type statusFile struct { status string @@ -118,6 +118,6 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "??", label: "new.txt", menuTitle: "new.txt"}, }) - assert.WorkingTreeFileCount(0) + assert.Model().WorkingTreeFileCount(0) }, }) diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 67a90ff6f..6bfbdb4db 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -28,12 +28,12 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ CreateFileAndAdd(postMergeFilename, postMergeFileContent) }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(3) + assert.Model().CommitCount(3) input.SwitchToCommitsView() mergeCommitMessage := "Merge branch 'feature-branch' into development-branch" - assert.HeadCommitMessage(Contains(mergeCommitMessage)) + assert.Model().HeadCommitMessage(Contains(mergeCommitMessage)) input.Press(keys.Commits.AmendToCommit) input.Confirmation(). @@ -42,8 +42,8 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ Confirm() // assuring we haven't added a brand new commit - assert.CommitCount(3) - assert.HeadCommitMessage(Contains(mergeCommitMessage)) + assert.Model().CommitCount(3) + assert.Model().HeadCommitMessage(Contains(mergeCommitMessage)) // assuring the post-merge file shows up in the merge commit. assert.Views().Main(). diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index 5f377eeab..4d12418c1 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -14,7 +14,7 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ }, SetupRepo: func(shell *Shell) {}, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(0) + assert.Model().CommitCount(0) input.Press(keys.Universal.Quit) input.Confirmation(). diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index 8f1281bc3..e506b150a 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -16,8 +16,8 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ shell.GitAddAll() }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.StashCount(0) - assert.WorkingTreeFileCount(1) + assert.Model().StashCount(0) + assert.Model().WorkingTreeFileCount(1) input.Press(keys.Files.ViewStashOptions) @@ -25,7 +25,7 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - assert.StashCount(1) - assert.WorkingTreeFileCount(0) + assert.Model().StashCount(1) + assert.Model().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 51cdbbc25..673bb1c04 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -17,8 +17,8 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ shell.GitAdd("file_1") }, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.StashCount(0) - assert.WorkingTreeFileCount(2) + assert.Model().StashCount(0) + assert.Model().WorkingTreeFileCount(2) input.Press(keys.Files.ViewStashOptions) @@ -26,7 +26,7 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - assert.StashCount(1) - assert.WorkingTreeFileCount(0) + assert.Model().StashCount(1) + assert.Model().WorkingTreeFileCount(0) }, }) From c5c9f5bb941342766f86626ad13d30e5ce01980e Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 15:56:02 +1100 Subject: [PATCH 07/20] rename --- pkg/integration/components/alert_asserter.go | 2 +- pkg/integration/components/assert.go | 7 +- .../commit_message_panel_asserter.go | 2 +- .../components/confirmation_asserter.go | 2 +- pkg/integration/components/input.go | 7 +- pkg/integration/components/menu_asserter.go | 2 +- pkg/integration/components/prompt_asserter.go | 2 +- pkg/integration/components/views.go | 111 ++++++++++++------ 8 files changed, 84 insertions(+), 51 deletions(-) diff --git a/pkg/integration/components/alert_asserter.go b/pkg/integration/components/alert_asserter.go index 8ca027b59..739f44256 100644 --- a/pkg/integration/components/alert_asserter.go +++ b/pkg/integration/components/alert_asserter.go @@ -7,7 +7,7 @@ type AlertAsserter struct { hasCheckedContent bool } -func (self *AlertAsserter) getViewAsserter() *Views { +func (self *AlertAsserter) getViewAsserter() *View { return self.assert.Views().ByName("confirmation") } diff --git a/pkg/integration/components/assert.go b/pkg/integration/components/assert.go index 42ef90d6f..531e4f4dc 100644 --- a/pkg/integration/components/assert.go +++ b/pkg/integration/components/assert.go @@ -7,7 +7,8 @@ import ( // through this struct we assert on the state of the lazygit gui type Assert struct { - gui integrationTypes.GuiDriver + input *Input + gui integrationTypes.GuiDriver *assertionHelper } @@ -16,8 +17,8 @@ func NewAssert(gui integrationTypes.GuiDriver) *Assert { } // for making assertions on lazygit views -func (self *Assert) Views() *ViewAsserterGetter { - return &ViewAsserterGetter{assert: self} +func (self *Assert) Views() *Views { + return &Views{assert: self, input: self.input} } // for making assertions on the lazygit model diff --git a/pkg/integration/components/commit_message_panel_asserter.go b/pkg/integration/components/commit_message_panel_asserter.go index 3a534bd2d..2d9ef834a 100644 --- a/pkg/integration/components/commit_message_panel_asserter.go +++ b/pkg/integration/components/commit_message_panel_asserter.go @@ -5,7 +5,7 @@ type CommitMessagePanelAsserter struct { input *Input } -func (self *CommitMessagePanelAsserter) getViewAsserter() *Views { +func (self *CommitMessagePanelAsserter) getViewAsserter() *View { return self.assert.Views().ByName("commitMessage") } diff --git a/pkg/integration/components/confirmation_asserter.go b/pkg/integration/components/confirmation_asserter.go index 9cf4d653d..4fe64fdb0 100644 --- a/pkg/integration/components/confirmation_asserter.go +++ b/pkg/integration/components/confirmation_asserter.go @@ -7,7 +7,7 @@ type ConfirmationAsserter struct { hasCheckedContent bool } -func (self *ConfirmationAsserter) getViewAsserter() *Views { +func (self *ConfirmationAsserter) getViewAsserter() *View { return self.assert.Views().ByName("confirmation") } diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index 2f1ed18c5..d525c61c6 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -18,11 +18,10 @@ type Input struct { pushKeyDelay int } -func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, assert *Assert, pushKeyDelay int) *Input { +func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, pushKeyDelay int) *Input { return &Input{ gui: gui, keys: keys, - assert: assert, pushKeyDelay: pushKeyDelay, assertionHelper: assert.assertionHelper, } @@ -53,14 +52,14 @@ func (self *Input) SwitchToStatusView() { self.assert.Views().Current().Name("status") } -func (self *Input) SwitchToFilesWindow() { +func (self *Input) switchToFilesWindow() { self.press(self.keys.Universal.JumpToBlock[1]) self.currentWindowName("files") } // switch to files window and assert that the files view is on top func (self *Input) SwitchToFilesView() { - self.SwitchToFilesWindow() + self.switchToFilesWindow() self.assert.Views().Current().Name("files") } diff --git a/pkg/integration/components/menu_asserter.go b/pkg/integration/components/menu_asserter.go index e302c235b..32191ac08 100644 --- a/pkg/integration/components/menu_asserter.go +++ b/pkg/integration/components/menu_asserter.go @@ -6,7 +6,7 @@ type MenuAsserter struct { hasCheckedTitle bool } -func (self *MenuAsserter) getViewAsserter() *Views { +func (self *MenuAsserter) getViewAsserter() *View { return self.assert.Views().ByName("menu") } diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go index b03ee85b7..fe7749e14 100644 --- a/pkg/integration/components/prompt_asserter.go +++ b/pkg/integration/components/prompt_asserter.go @@ -6,7 +6,7 @@ type PromptAsserter struct { hasCheckedTitle bool } -func (self *PromptAsserter) getViewAsserter() *Views { +func (self *PromptAsserter) getViewAsserter() *View { return self.assert.Views().ByName("confirmation") } diff --git a/pkg/integration/components/views.go b/pkg/integration/components/views.go index 624d1f66e..0c339dbe9 100644 --- a/pkg/integration/components/views.go +++ b/pkg/integration/components/views.go @@ -7,15 +7,57 @@ import ( ) type Views struct { + assert *Assert + input *Input +} + +func (self *Views) Current() *View { + return &View{ + context: "current view", + getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() }, + assert: self.assert, + input: self.input, + } +} + +func (self *Views) Main() *View { + return &View{ + context: "main view", + getView: func() *gocui.View { return self.assert.gui.MainView() }, + assert: self.assert, + input: self.input, + } +} + +func (self *Views) Secondary() *View { + return &View{ + context: "secondary view", + getView: func() *gocui.View { return self.assert.gui.SecondaryView() }, + assert: self.assert, + input: self.input, + } +} + +func (self *Views) ByName(viewName string) *View { + return &View{ + context: fmt.Sprintf("%s view", viewName), + getView: func() *gocui.View { return self.assert.gui.View(viewName) }, + assert: self.assert, + input: self.input, + } +} + +type View struct { // context is prepended to any error messages e.g. 'context: "current view"' context string getView func() *gocui.View assert *Assert + input *Input } // asserts that the view has the expected name. This is typically used in tandem with the CurrentView method i.e.; // assert.CurrentView().Name("commits") to assert that the current view is the commits view. -func (self *Views) Name(expected string) *Views { +func (self *View) Name(expected string) *View { self.assert.assertWithRetries(func() (bool, string) { actual := self.getView().Name() return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual) @@ -25,7 +67,7 @@ func (self *Views) Name(expected string) *Views { } // asserts that the view has the expected title -func (self *Views) Title(expected *matcher) *Views { +func (self *View) Title(expected *matcher) *View { self.assert.assertWithRetries(func() (bool, string) { actual := self.getView().Title return expected.context(fmt.Sprintf("%s title", self.context)).test(actual) @@ -38,7 +80,7 @@ func (self *Views) Title(expected *matcher) *Views { // are passed, we only check the first three lines of the view. // This method is convenient when you have a list of commits but you only want to // assert on the first couple of commits. -func (self *Views) TopLines(matchers ...*matcher) *Views { +func (self *View) TopLines(matchers ...*matcher) *View { self.assert.assertWithRetries(func() (bool, string) { lines := self.getView().BufferLines() return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines)) @@ -49,7 +91,7 @@ func (self *Views) TopLines(matchers ...*matcher) *Views { // 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. -func (self *Views) Lines(matchers ...*matcher) *Views { +func (self *View) Lines(matchers ...*matcher) *View { self.assert.assertWithRetries(func() (bool, string) { lines := self.getView().BufferLines() return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines)) @@ -58,7 +100,7 @@ func (self *Views) Lines(matchers ...*matcher) *Views { return self.assertLines(matchers...) } -func (self *Views) assertLines(matchers ...*matcher) *Views { +func (self *View) assertLines(matchers ...*matcher) *View { view := self.getView() for i, matcher := range matchers { @@ -82,7 +124,7 @@ func (self *Views) assertLines(matchers ...*matcher) *Views { } // asserts on the content of the view i.e. the stuff within the view's frame. -func (self *Views) Content(matcher *matcher) *Views { +func (self *View) Content(matcher *matcher) *View { self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), func() string { return self.getView().Buffer() @@ -93,7 +135,7 @@ func (self *Views) Content(matcher *matcher) *Views { } // asserts on the selected line of the view -func (self *Views) SelectedLine(matcher *matcher) *Views { +func (self *View) SelectedLine(matcher *matcher) *View { self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context), func() string { return self.getView().SelectedLine() @@ -104,7 +146,7 @@ func (self *Views) SelectedLine(matcher *matcher) *Views { } // asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view. -func (self *Views) SelectedLineIdx(expected int) *Views { +func (self *View) SelectedLineIdx(expected int) *View { self.assert.assertWithRetries(func() (bool, string) { actual := self.getView().SelectedLineIdx() return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual) @@ -113,38 +155,29 @@ func (self *Views) SelectedLineIdx(expected int) *Views { return self } -type ViewAsserterGetter struct { - assert *Assert -} +// func (self *View) Focus() *View { +// // we can easily change focus by switching to the view's window, but this assumes that the desired view +// // is at the top of that window. So for now we'll switch to the window then assert that the desired +// // view is on top (i.e. that it's the current view). +// whitelistedViewNames := []string{"status", "files", "localBranches", "commits", "stash"} -func (self *ViewAsserterGetter) Current() *Views { - return &Views{ - context: "current view", - getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() }, - assert: self.assert, - } -} +// viewName := self.getView().Name() -func (self *ViewAsserterGetter) Main() *Views { - return &Views{ - context: "main view", - getView: func() *gocui.View { return self.assert.gui.MainView() }, - assert: self.assert, - } -} +// if !lo.Contains(whitelistedViewNames, self.getView().Name()) { +// self.assert.fail(fmt.Sprintf("Cannot focus view %s: Focus() method not implemented", viewName)) +// } -func (self *ViewAsserterGetter) Secondary() *Views { - return &Views{ - context: "secondary view", - getView: func() *gocui.View { return self.assert.gui.SecondaryView() }, - assert: self.assert, - } -} +// windowIndexMap := map[string]int{ +// "status": 0, +// "files": 1, +// "localBranches": 2, +// "commits": 3, +// "stash": 4, +// } -func (self *ViewAsserterGetter) ByName(viewName string) *Views { - return &Views{ - context: fmt.Sprintf("%s view", viewName), - getView: func() *gocui.View { return self.assert.gui.View(viewName) }, - assert: self.assert, - } -} +// self.input.switchToFilesWindow() +// self.press(self.keys.Universal.JumpToBlock[1]) +// self.assert.Views().Current().Name(viewName) + +// return self +// } From b166b8f776e45c77a94b6e919f3b9460ff3c2e06 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 16:27:36 +1100 Subject: [PATCH 08/20] combine assert and input structs, clean up interface --- pkg/integration/README.md | 4 +- pkg/integration/components/alert_asserter.go | 9 +- pkg/integration/components/assert.go | 38 ---- .../commit_message_panel_asserter.go | 13 +- .../components/confirmation_asserter.go | 9 +- pkg/integration/components/input.go | 174 +++++----------- pkg/integration/components/menu_asserter.go | 11 +- pkg/integration/components/model.go | 24 ++- pkg/integration/components/prompt_asserter.go | 29 +-- pkg/integration/components/test.go | 8 +- pkg/integration/components/test_test.go | 20 +- pkg/integration/components/view.go | 196 ++++++++++++++++++ pkg/integration/components/views.go | 182 ++++++---------- pkg/integration/tests/bisect/basic.go | 45 ++-- .../tests/bisect/from_other_branch.go | 34 ++- .../tests/branch/checkout_by_name.go | 25 ++- pkg/integration/tests/branch/delete.go | 29 +-- pkg/integration/tests/branch/rebase.go | 50 ++--- .../tests/branch/rebase_and_drop.go | 75 ++++--- pkg/integration/tests/branch/reset.go | 35 ++-- pkg/integration/tests/branch/suggestions.go | 12 +- .../tests/cherry_pick/cherry_pick.go | 89 ++++---- .../cherry_pick/cherry_pick_conflicts.go | 107 +++++----- pkg/integration/tests/commit/commit.go | 20 +- .../tests/commit/commit_multiline.go | 20 +- pkg/integration/tests/commit/new_branch.go | 28 +-- pkg/integration/tests/commit/revert.go | 24 +-- pkg/integration/tests/commit/staged.go | 49 +++-- .../tests/commit/staged_without_hooks.go | 39 ++-- pkg/integration/tests/commit/unstaged.go | 39 ++-- .../tests/config/remote_named_star.go | 3 +- .../tests/custom_commands/basic.go | 14 +- .../tests/custom_commands/form_prompts.go | 19 +- .../custom_commands/menu_from_command.go | 20 +- .../menu_from_commands_output.go | 17 +- .../tests/custom_commands/multiple_prompts.go | 19 +- pkg/integration/tests/diff/diff.go | 71 ++++--- .../tests/diff/diff_and_apply_patch.go | 76 ++++--- pkg/integration/tests/diff/diff_commits.go | 47 +++-- .../tests/file/dir_with_untracked_file.go | 6 +- pkg/integration/tests/file/discard_changes.go | 17 +- .../tests/interactive_rebase/amend_merge.go | 21 +- .../tests/interactive_rebase/one.go | 99 +++++---- pkg/integration/tests/misc/confirm_on_quit.go | 11 +- pkg/integration/tests/stash/rename.go | 22 +- pkg/integration/tests/stash/stash.go | 17 +- .../stash/stash_including_untracked_files.go | 17 +- 47 files changed, 1021 insertions(+), 912 deletions(-) delete mode 100644 pkg/integration/components/assert.go create mode 100644 pkg/integration/components/view.go diff --git a/pkg/integration/README.md b/pkg/integration/README.md index d05e45f0c..fe4f43ac1 100644 --- a/pkg/integration/README.md +++ b/pkg/integration/README.md @@ -48,8 +48,8 @@ Try to do as much setup work as possible in your setup step. For example, if all 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() +input.press(keys.Files.CommitChanges) +input.InCommitMessagePanel() ``` Note that there are some `input` methods that have assertions baked in, such as the `SwitchToView` methods. diff --git a/pkg/integration/components/alert_asserter.go b/pkg/integration/components/alert_asserter.go index 739f44256..abc2f1171 100644 --- a/pkg/integration/components/alert_asserter.go +++ b/pkg/integration/components/alert_asserter.go @@ -1,14 +1,13 @@ package components type AlertAsserter struct { - assert *Assert input *Input hasCheckedTitle bool hasCheckedContent bool } func (self *AlertAsserter) getViewAsserter() *View { - return self.assert.Views().ByName("confirmation") + return self.input.Views().Confirmation() } // asserts that the alert view has the expected title @@ -32,17 +31,17 @@ func (self *AlertAsserter) Content(expected *matcher) *AlertAsserter { func (self *AlertAsserter) Confirm() { self.checkNecessaryChecksCompleted() - self.input.Confirm() + self.getViewAsserter().PressEnter() } func (self *AlertAsserter) Cancel() { self.checkNecessaryChecksCompleted() - self.input.Press(self.input.keys.Universal.Return) + self.getViewAsserter().PressEscape() } func (self *AlertAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedContent || !self.hasCheckedTitle { - self.assert.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") + self.input.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") } } diff --git a/pkg/integration/components/assert.go b/pkg/integration/components/assert.go deleted file mode 100644 index 531e4f4dc..000000000 --- a/pkg/integration/components/assert.go +++ /dev/null @@ -1,38 +0,0 @@ -package components - -import ( - integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" -) - -// through this struct we assert on the state of the lazygit gui - -type Assert struct { - input *Input - gui integrationTypes.GuiDriver - *assertionHelper -} - -func NewAssert(gui integrationTypes.GuiDriver) *Assert { - return &Assert{gui: gui} -} - -// for making assertions on lazygit views -func (self *Assert) Views() *Views { - return &Views{assert: self, input: self.input} -} - -// for making assertions on the lazygit model -func (self *Assert) Model() *Model { - return &Model{assertionHelper: self.assertionHelper, gui: self.gui} -} - -// for making assertions on the file system -func (self *Assert) FileSystem() *FileSystem { - return &FileSystem{assertionHelper: self.assertionHelper} -} - -// for when you just want to fail the test yourself. -// This runs callbacks to ensure we render the error after closing the gui. -func (self *Assert) Fail(message string) { - self.assertionHelper.fail(message) -} diff --git a/pkg/integration/components/commit_message_panel_asserter.go b/pkg/integration/components/commit_message_panel_asserter.go index 2d9ef834a..9aacacf89 100644 --- a/pkg/integration/components/commit_message_panel_asserter.go +++ b/pkg/integration/components/commit_message_panel_asserter.go @@ -1,12 +1,11 @@ package components type CommitMessagePanelAsserter struct { - assert *Assert - input *Input + input *Input } func (self *CommitMessagePanelAsserter) getViewAsserter() *View { - return self.assert.Views().ByName("commitMessage") + return self.input.Views().CommitMessage() } // asserts on the text initially present in the prompt @@ -17,13 +16,13 @@ func (self *CommitMessagePanelAsserter) InitialText(expected *matcher) *CommitMe } func (self *CommitMessagePanelAsserter) Type(value string) *CommitMessagePanelAsserter { - self.input.Type(value) + self.input.typeContent(value) return self } func (self *CommitMessagePanelAsserter) AddNewline() *CommitMessagePanelAsserter { - self.input.Press(self.input.keys.Universal.AppendNewline) + self.input.press(self.input.keys.Universal.AppendNewline) return self } @@ -33,9 +32,9 @@ func (self *CommitMessagePanelAsserter) Clear() *CommitMessagePanelAsserter { } func (self *CommitMessagePanelAsserter) Confirm() { - self.input.Confirm() + self.getViewAsserter().PressEnter() } func (self *CommitMessagePanelAsserter) Cancel() { - self.input.Press(self.input.keys.Universal.Return) + self.getViewAsserter().PressEscape() } diff --git a/pkg/integration/components/confirmation_asserter.go b/pkg/integration/components/confirmation_asserter.go index 4fe64fdb0..2d3d87ba0 100644 --- a/pkg/integration/components/confirmation_asserter.go +++ b/pkg/integration/components/confirmation_asserter.go @@ -1,14 +1,13 @@ package components type ConfirmationAsserter struct { - assert *Assert input *Input hasCheckedTitle bool hasCheckedContent bool } func (self *ConfirmationAsserter) getViewAsserter() *View { - return self.assert.Views().ByName("confirmation") + return self.input.Views().Confirmation() } // asserts that the confirmation view has the expected title @@ -32,17 +31,17 @@ func (self *ConfirmationAsserter) Content(expected *matcher) *ConfirmationAssert func (self *ConfirmationAsserter) Confirm() { self.checkNecessaryChecksCompleted() - self.input.Confirm() + self.getViewAsserter().PressEnter() } func (self *ConfirmationAsserter) Cancel() { self.checkNecessaryChecksCompleted() - self.input.Press(self.input.keys.Universal.Return) + self.getViewAsserter().PressEscape() } func (self *ConfirmationAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedContent || !self.hasCheckedTitle { - self.assert.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") + self.input.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") } } diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index d525c61c6..d5db33518 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -8,14 +8,14 @@ import ( "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/types" integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" + "github.com/samber/lo" ) type Input struct { - gui integrationTypes.GuiDriver - keys config.KeybindingConfig - assert *Assert - *assertionHelper + gui integrationTypes.GuiDriver + keys config.KeybindingConfig pushKeyDelay int + *assertionHelper } func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, pushKeyDelay int) *Input { @@ -23,119 +23,31 @@ func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, push gui: gui, keys: keys, pushKeyDelay: pushKeyDelay, - assertionHelper: assert.assertionHelper, + assertionHelper: &assertionHelper{gui: gui}, } } // 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) Press(keyStrs ...string) { - for _, keyStr := range keyStrs { - self.press(keyStr) - } -} - func (self *Input) press(keyStr string) { self.Wait(self.pushKeyDelay) self.gui.PressKey(keyStr) } -func (self *Input) SwitchToStatusWindow() { - self.press(self.keys.Universal.JumpToBlock[0]) - self.currentWindowName("status") -} - -// switch to status window and assert that the status view is on top -func (self *Input) SwitchToStatusView() { - self.SwitchToStatusWindow() - self.assert.Views().Current().Name("status") -} - -func (self *Input) switchToFilesWindow() { - self.press(self.keys.Universal.JumpToBlock[1]) - self.currentWindowName("files") -} - -// switch to files window and assert that the files view is on top -func (self *Input) SwitchToFilesView() { - self.switchToFilesWindow() - self.assert.Views().Current().Name("files") -} - -func (self *Input) SwitchToBranchesWindow() { - self.press(self.keys.Universal.JumpToBlock[2]) - self.currentWindowName("localBranches") -} - -// switch to branches window and assert that the branches view is on top -func (self *Input) SwitchToBranchesView() { - self.SwitchToBranchesWindow() - self.assert.Views().Current().Name("localBranches") -} - -func (self *Input) SwitchToCommitsWindow() { - self.press(self.keys.Universal.JumpToBlock[3]) - self.currentWindowName("commits") -} - -// switch to commits window and assert that the commits view is on top -func (self *Input) SwitchToCommitsView() { - self.SwitchToCommitsWindow() - self.assert.Views().Current().Name("commits") -} - -func (self *Input) SwitchToStashWindow() { - self.press(self.keys.Universal.JumpToBlock[4]) - self.currentWindowName("stash") -} - -// switch to stash window and assert that the stash view is on top -func (self *Input) SwitchToStashView() { - self.SwitchToStashWindow() - self.assert.Views().Current().Name("stash") -} - -func (self *Input) Type(content string) { +func (self *Input) typeContent(content string) { for _, char := range content { self.press(string(char)) } } -// i.e. pressing enter -func (self *Input) Confirm() { - self.press(self.keys.Universal.Confirm) -} - -// i.e. same as Confirm -func (self *Input) Enter() { - self.press(self.keys.Universal.Confirm) -} - -// i.e. pressing escape -func (self *Input) Cancel() { - self.press(self.keys.Universal.Return) -} - -// i.e. pressing space -func (self *Input) PrimaryAction() { - self.press(self.keys.Universal.Select) -} - -// i.e. pressing down arrow -func (self *Input) NextItem() { - self.press(self.keys.Universal.NextItem) -} - -// i.e. pressing up arrow -func (self *Input) PreviousItem() { - self.press(self.keys.Universal.PrevItem) -} - func (self *Input) ContinueMerge() { - self.Press(self.keys.Universal.CreateRebaseOptionsMenu) - self.assert.Views().Current().SelectedLine(Contains("continue")) - self.Confirm() + self.Views().current().Press(self.keys.Universal.CreateRebaseOptionsMenu) + + self.ExpectMenu(). + Title(Equals("Rebase Options")). + Select(Contains("continue")). + Confirm() } func (self *Input) ContinueRebase() { @@ -166,7 +78,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) NavigateToListItem(matcher *matcher) { +func (self *Input) navigateToListItem(matcher *matcher) { self.inListContext() currentContext := self.gui.CurrentContext().(types.IListContext) @@ -175,7 +87,7 @@ func (self *Input) NavigateToListItem(matcher *matcher) { var matchIndex int - self.assert.assertWithRetries(func() (bool, string) { + self.assertWithRetries(func() (bool, string) { matchIndex = -1 var matches []string lines := view.ViewBufferLines() @@ -198,20 +110,20 @@ func (self *Input) NavigateToListItem(matcher *matcher) { selectedLineIdx := view.SelectedLineIdx() if selectedLineIdx == matchIndex { - self.assert.Views().Current().SelectedLine(matcher) + self.Views().current().SelectedLine(matcher) return } if selectedLineIdx < matchIndex { for i := selectedLineIdx; i < matchIndex; i++ { - self.NextItem() + self.Views().current().SelectNextItem() } - self.assert.Views().Current().SelectedLine(matcher) + self.Views().current().SelectedLine(matcher) return } else { for i := selectedLineIdx; i > matchIndex; i-- { - self.PreviousItem() + self.Views().current().SelectPreviousItem() } - self.assert.Views().Current().SelectedLine(matcher) + self.Views().current().SelectedLine(matcher) return } } @@ -224,10 +136,10 @@ func (self *Input) inListContext() { }) } -func (self *Input) Confirmation() *ConfirmationAsserter { +func (self *Input) ExpectConfirmation() *ConfirmationAsserter { self.inConfirm() - return &ConfirmationAsserter{assert: self.assert, input: self} + return &ConfirmationAsserter{input: self} } func (self *Input) inConfirm() { @@ -237,10 +149,10 @@ func (self *Input) inConfirm() { }) } -func (self *Input) Prompt() *PromptAsserter { +func (self *Input) ExpectPrompt() *PromptAsserter { self.inPrompt() - return &PromptAsserter{assert: self.assert, input: self} + return &PromptAsserter{input: self} } func (self *Input) inPrompt() { @@ -250,10 +162,10 @@ func (self *Input) inPrompt() { }) } -func (self *Input) Alert() *AlertAsserter { +func (self *Input) ExpectAlert() *AlertAsserter { self.inAlert() - return &AlertAsserter{assert: self.assert, input: self} + return &AlertAsserter{input: self} } func (self *Input) inAlert() { @@ -264,10 +176,10 @@ func (self *Input) inAlert() { }) } -func (self *Input) Menu() *MenuAsserter { +func (self *Input) ExpectMenu() *MenuAsserter { self.inMenu() - return &MenuAsserter{assert: self.assert, input: self} + return &MenuAsserter{input: self} } func (self *Input) inMenu() { @@ -276,10 +188,10 @@ func (self *Input) inMenu() { }) } -func (self *Input) CommitMessagePanel() *CommitMessagePanelAsserter { +func (self *Input) ExpectCommitMessagePanel() *CommitMessagePanelAsserter { self.inCommitMessagePanel() - return &CommitMessagePanelAsserter{assert: self.assert, input: self} + return &CommitMessagePanelAsserter{input: self} } func (self *Input) inCommitMessagePanel() { @@ -295,3 +207,31 @@ func (self *Input) currentWindowName(expectedWindowName string) { return actual == expectedWindowName, fmt.Sprintf("Expected current window name to be '%s', but got '%s'", expectedWindowName, actual) }) } + +// for making assertions on lazygit views +func (self *Input) Views() *Views { + return &Views{input: self} +} + +// for making assertions on the lazygit model +func (self *Input) Model() *Model { + return &Model{assertionHelper: self.assertionHelper, gui: self.gui} +} + +// for making assertions on the file system +func (self *Input) FileSystem() *FileSystem { + return &FileSystem{assertionHelper: self.assertionHelper} +} + +// for when you just want to fail the test yourself. +// This runs callbacks to ensure we render the error after closing the gui. +func (self *Input) Fail(message string) { + self.assertionHelper.fail(message) +} + +func (self *Input) NotInPopup() { + self.assertWithRetries(func() (bool, string) { + viewName := self.gui.CurrentContext().GetView().Name() + return !lo.Contains([]string{"menu", "confirmation", "commitMessage"}, viewName), fmt.Sprintf("Unexpected popup view present: %s view", viewName) + }) +} diff --git a/pkg/integration/components/menu_asserter.go b/pkg/integration/components/menu_asserter.go index 32191ac08..4f1fd035a 100644 --- a/pkg/integration/components/menu_asserter.go +++ b/pkg/integration/components/menu_asserter.go @@ -1,13 +1,12 @@ package components type MenuAsserter struct { - assert *Assert input *Input hasCheckedTitle bool } func (self *MenuAsserter) getViewAsserter() *View { - return self.assert.Views().ByName("menu") + return self.input.Views().Menu() } // asserts that the popup has the expected title @@ -22,23 +21,23 @@ func (self *MenuAsserter) Title(expected *matcher) *MenuAsserter { func (self *MenuAsserter) Confirm() { self.checkNecessaryChecksCompleted() - self.input.Confirm() + self.getViewAsserter().PressEnter() } func (self *MenuAsserter) Cancel() { self.checkNecessaryChecksCompleted() - self.input.Press(self.input.keys.Universal.Return) + self.getViewAsserter().PressEscape() } func (self *MenuAsserter) Select(option *matcher) *MenuAsserter { - self.input.NavigateToListItem(option) + self.getViewAsserter().NavigateToListItem(option) return self } func (self *MenuAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedTitle { - self.assert.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().") + self.input.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().") } } diff --git a/pkg/integration/components/model.go b/pkg/integration/components/model.go index 83d2e97e8..368c50852 100644 --- a/pkg/integration/components/model.go +++ b/pkg/integration/components/model.go @@ -11,7 +11,7 @@ type Model struct { gui integrationTypes.GuiDriver } -func (self *Model) WorkingTreeFileCount(expectedCount int) { +func (self *Model) WorkingTreeFileCount(expectedCount int) *Model { self.assertWithRetries(func() (bool, string) { actualCount := len(self.gui.Model().Files) @@ -20,9 +20,11 @@ func (self *Model) WorkingTreeFileCount(expectedCount int) { expectedCount, actualCount, ) }) + + return self } -func (self *Model) CommitCount(expectedCount int) { +func (self *Model) CommitCount(expectedCount int) *Model { self.assertWithRetries(func() (bool, string) { actualCount := len(self.gui.Model().Commits) @@ -31,9 +33,11 @@ func (self *Model) CommitCount(expectedCount int) { expectedCount, actualCount, ) }) + + return self } -func (self *Model) StashCount(expectedCount int) { +func (self *Model) StashCount(expectedCount int) *Model { self.assertWithRetries(func() (bool, string) { actualCount := len(self.gui.Model().StashEntries) @@ -42,17 +46,21 @@ func (self *Model) StashCount(expectedCount int) { expectedCount, actualCount, ) }) + + return self } -func (self *Model) AtLeastOneCommit() { +func (self *Model) AtLeastOneCommit() *Model { self.assertWithRetries(func() (bool, string) { actualCount := len(self.gui.Model().Commits) return actualCount > 0, "Expected at least one commit present" }) + + return self } -func (self *Model) HeadCommitMessage(matcher *matcher) { +func (self *Model) HeadCommitMessage(matcher *matcher) *Model { self.assertWithRetries(func() (bool, string) { return len(self.gui.Model().Commits) > 0, "Expected at least one commit to be present" }) @@ -62,11 +70,15 @@ func (self *Model) HeadCommitMessage(matcher *matcher) { return self.gui.Model().Commits[0].Name }, ) + + return self } -func (self *Model) CurrentBranchName(expectedViewName string) { +func (self *Model) CurrentBranchName(expectedViewName string) *Model { self.assertWithRetries(func() (bool, string) { actual := self.gui.CheckedOutRef().Name return actual == expectedViewName, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expectedViewName, actual) }) + + return self } diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go index fe7749e14..343d9d54b 100644 --- a/pkg/integration/components/prompt_asserter.go +++ b/pkg/integration/components/prompt_asserter.go @@ -1,13 +1,12 @@ package components type PromptAsserter struct { - assert *Assert input *Input hasCheckedTitle bool } func (self *PromptAsserter) getViewAsserter() *View { - return self.assert.Views().ByName("confirmation") + return self.input.Views().Confirmation() } // asserts that the popup has the expected title @@ -27,7 +26,7 @@ func (self *PromptAsserter) InitialText(expected *matcher) *PromptAsserter { } func (self *PromptAsserter) Type(value string) *PromptAsserter { - self.input.Type(value) + self.input.typeContent(value) return self } @@ -39,45 +38,47 @@ func (self *PromptAsserter) Clear() *PromptAsserter { func (self *PromptAsserter) Confirm() { self.checkNecessaryChecksCompleted() - self.input.Confirm() + self.getViewAsserter().PressEnter() } func (self *PromptAsserter) Cancel() { self.checkNecessaryChecksCompleted() - self.input.Press(self.input.keys.Universal.Return) + self.getViewAsserter().PressEscape() } func (self *PromptAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedTitle { - self.assert.Fail("You must check the title of a prompt popup by calling Title() before calling Confirm()/Cancel().") + self.input.Fail("You must check the title of a prompt popup by calling Title() before calling Confirm()/Cancel().") } } func (self *PromptAsserter) SuggestionLines(matchers ...*matcher) *PromptAsserter { - self.assert.Views().ByName("suggestions").Lines(matchers...) + self.input.Views().Suggestions().Lines(matchers...) return self } func (self *PromptAsserter) SuggestionTopLines(matchers ...*matcher) *PromptAsserter { - self.assert.Views().ByName("suggestions").TopLines(matchers...) + self.input.Views().Suggestions().TopLines(matchers...) return self } func (self *PromptAsserter) SelectFirstSuggestion() *PromptAsserter { - self.input.Press(self.input.keys.Universal.TogglePanel) - self.assert.Views().Current().Name("suggestions") + self.input.press(self.input.keys.Universal.TogglePanel) + self.input.Views().Suggestions(). + IsFocused(). + SelectedLineIdx(0) return self } func (self *PromptAsserter) SelectSuggestion(matcher *matcher) *PromptAsserter { - self.input.Press(self.input.keys.Universal.TogglePanel) - self.assert.Views().Current().Name("suggestions") - - self.input.NavigateToListItem(matcher) + self.input.press(self.input.keys.Universal.TogglePanel) + self.input.Views().Suggestions(). + IsFocused(). + NavigateToListItem(matcher) return self } diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go index 46c0d4055..705323ecb 100644 --- a/pkg/integration/components/test.go +++ b/pkg/integration/components/test.go @@ -26,7 +26,6 @@ type IntegrationTest struct { run func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) } @@ -41,7 +40,7 @@ type NewIntegrationTestArgs struct { // takes a config and mutates. The mutated context will end up being passed to the gui SetupConfig func(config *config.AppConfig) // runs the test - Run func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) + Run func(shell *Shell, input *Input, keys config.KeybindingConfig) // additional args passed to lazygit ExtraCmdArgs string // for when a test is flakey @@ -94,11 +93,10 @@ func (self *IntegrationTest) SetupRepo(shell *Shell) { // I want access to all contexts, the model, the ability to press a key, the ability to log, func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) { shell := NewShell("/tmp/lazygit-test") - assert := NewAssert(gui) keys := gui.Keys() - input := NewInput(gui, keys, assert, KeyPressDelay()) + input := NewInput(gui, keys, KeyPressDelay()) - self.run(shell, input, assert, keys) + self.run(shell, input, keys) if KeyPressDelay() > 0 { // the dev would want to see the final state if they're running in slow mode diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index eb901a402..1356fbf3b 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -63,10 +63,10 @@ func (self *fakeGuiDriver) View(viewName string) *gocui.View { func TestAssertionFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.Press("a") - input.Press("b") - assert.Model().CommitCount(2) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.press("a") + input.press("b") + input.Model().CommitCount(2) }, }) driver := &fakeGuiDriver{} @@ -78,8 +78,8 @@ func TestAssertionFailure(t *testing.T) { func TestManualFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Fail("blah") + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Fail("blah") }, }) driver := &fakeGuiDriver{} @@ -90,10 +90,10 @@ func TestManualFailure(t *testing.T) { func TestSuccess(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.Press("a") - input.Press("b") - assert.Model().CommitCount(0) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.press("a") + input.press("b") + input.Model().CommitCount(0) }, }) driver := &fakeGuiDriver{} diff --git a/pkg/integration/components/view.go b/pkg/integration/components/view.go new file mode 100644 index 000000000..e94d0d60c --- /dev/null +++ b/pkg/integration/components/view.go @@ -0,0 +1,196 @@ +package components + +import ( + "fmt" + + "github.com/jesseduffield/gocui" +) + +type View struct { + // context is prepended to any error messages e.g. 'context: "current view"' + context string + getView func() *gocui.View + input *Input +} + +// asserts that the view has the expected name. This is typically used in tandem with the CurrentView method i.e.; +// input.CurrentView().Name("commits") to assert that the current view is the commits view. +func (self *View) Name(expected string) *View { + self.input.assertWithRetries(func() (bool, string) { + actual := self.getView().Name() + return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual) + }) + + return self +} + +// asserts that the view has the expected title +func (self *View) Title(expected *matcher) *View { + self.input.assertWithRetries(func() (bool, string) { + actual := self.getView().Title + return expected.context(fmt.Sprintf("%s title", self.context)).test(actual) + }) + + return self +} + +// asserts that the view has lines matching the given matchers. So if three matchers +// are passed, we only check the first three lines of the view. +// This method is convenient when you have a list of commits but you only want to +// assert on the first couple of commits. +func (self *View) TopLines(matchers ...*matcher) *View { + self.input.assertWithRetries(func() (bool, string) { + lines := self.getView().BufferLines() + return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines)) + }) + + return self.assertLines(matchers...) +} + +// 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. +func (self *View) Lines(matchers ...*matcher) *View { + self.input.assertWithRetries(func() (bool, string) { + lines := self.getView().BufferLines() + return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines)) + }) + + return self.assertLines(matchers...) +} + +func (self *View) assertLines(matchers ...*matcher) *View { + view := self.getView() + + for i, matcher := range matchers { + checkIsSelected, matcher := matcher.checkIsSelected() + + self.input.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()), + func() string { + return view.BufferLines()[i] + }, + ) + + if checkIsSelected { + self.input.assertWithRetries(func() (bool, string) { + lineIdx := view.SelectedLineIdx() + return lineIdx == i, fmt.Sprintf("Unexpected selected line index in view '%s'. Expected %d, got %d", view.Name(), i, lineIdx) + }) + } + } + + return self +} + +// asserts on the content of the view i.e. the stuff within the view's frame. +func (self *View) Content(matcher *matcher) *View { + self.input.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), + func() string { + return self.getView().Buffer() + }, + ) + + return self +} + +// asserts on the selected line of the view +func (self *View) SelectedLine(matcher *matcher) *View { + self.input.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context), + func() string { + return self.getView().SelectedLine() + }, + ) + + return self +} + +// asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view. +func (self *View) SelectedLineIdx(expected int) *View { + self.input.assertWithRetries(func() (bool, string) { + actual := self.getView().SelectedLineIdx() + return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual) + }) + + return self +} + +// focus the view (assumes the view is a side-view that can be focused via a keybinding) +func (self *View) Focus() *View { + // we can easily change focus by switching to the view's window, but this assumes that the desired view + // is at the top of that window. So for now we'll switch to the window then assert that the desired + // view is on top (i.e. that it's the current view). + // If we want to support other views e.g. the tags view, we'll need to add more logic here. + viewName := self.getView().Name() + + // using a map rather than a slice because we might add other views which share a window index later + windowIndexMap := map[string]int{ + "status": 0, + "files": 1, + "localBranches": 2, + "commits": 3, + "stash": 4, + } + + index, ok := windowIndexMap[viewName] + if !ok { + self.input.fail(fmt.Sprintf("Cannot focus view %s: Focus() method not implemented", viewName)) + } + + self.input.press(self.input.keys.Universal.JumpToBlock[index]) + + // assert that we land in the expected view + self.IsFocused() + + return self +} + +// asserts that the view is focused +func (self *View) IsFocused() *View { + self.input.assertWithRetries(func() (bool, string) { + expected := self.getView().Name() + actual := self.input.gui.CurrentContext().GetView().Name() + return actual == expected, fmt.Sprintf("%s: Unexpected view focused. Expected %s, got %s", self.context, expected, actual) + }) + + return self +} + +func (self *View) Press(keyStr string) *View { + self.IsFocused() + + self.input.press(keyStr) + + return self +} + +// i.e. pressing down arrow +func (self *View) SelectNextItem() *View { + return self.Press(self.input.keys.Universal.NextItem) +} + +// i.e. pressing up arrow +func (self *View) SelectPreviousItem() *View { + return self.Press(self.input.keys.Universal.PrevItem) +} + +// i.e. pressing space +func (self *View) PressPrimaryAction() *View { + return self.Press(self.input.keys.Universal.Select) +} + +// i.e. pressing space +func (self *View) PressEnter() *View { + return self.Press(self.input.keys.Universal.Confirm) +} + +// i.e. pressing escape +func (self *View) PressEscape() *View { + return self.Press(self.input.keys.Universal.Return) +} + +func (self *View) NavigateToListItem(matcher *matcher) *View { + self.IsFocused() + + self.input.navigateToListItem(matcher) + + return self +} diff --git a/pkg/integration/components/views.go b/pkg/integration/components/views.go index 0c339dbe9..9efe7cdcf 100644 --- a/pkg/integration/components/views.go +++ b/pkg/integration/components/views.go @@ -7,15 +7,15 @@ import ( ) type Views struct { - assert *Assert - input *Input + input *Input } -func (self *Views) Current() *View { +// not exporting this because I want the test to always be explicit about what +// view it's dealing with. +func (self *Views) current() *View { return &View{ context: "current view", - getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() }, - assert: self.assert, + getView: func() *gocui.View { return self.input.gui.CurrentContext().GetView() }, input: self.input, } } @@ -23,8 +23,7 @@ func (self *Views) Current() *View { func (self *Views) Main() *View { return &View{ context: "main view", - getView: func() *gocui.View { return self.assert.gui.MainView() }, - assert: self.assert, + getView: func() *gocui.View { return self.input.gui.MainView() }, input: self.input, } } @@ -32,8 +31,7 @@ func (self *Views) Main() *View { func (self *Views) Secondary() *View { return &View{ context: "secondary view", - getView: func() *gocui.View { return self.assert.gui.SecondaryView() }, - assert: self.assert, + getView: func() *gocui.View { return self.input.gui.SecondaryView() }, input: self.input, } } @@ -41,143 +39,83 @@ func (self *Views) Secondary() *View { func (self *Views) ByName(viewName string) *View { return &View{ context: fmt.Sprintf("%s view", viewName), - getView: func() *gocui.View { return self.assert.gui.View(viewName) }, - assert: self.assert, + getView: func() *gocui.View { return self.input.gui.View(viewName) }, input: self.input, } } -type View struct { - // context is prepended to any error messages e.g. 'context: "current view"' - context string - getView func() *gocui.View - assert *Assert - input *Input +func (self *Views) Commits() *View { + return self.ByName("commits") } -// asserts that the view has the expected name. This is typically used in tandem with the CurrentView method i.e.; -// assert.CurrentView().Name("commits") to assert that the current view is the commits view. -func (self *View) Name(expected string) *View { - self.assert.assertWithRetries(func() (bool, string) { - actual := self.getView().Name() - return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual) - }) - - return self +func (self *Views) Files() *View { + return self.ByName("files") } -// asserts that the view has the expected title -func (self *View) Title(expected *matcher) *View { - self.assert.assertWithRetries(func() (bool, string) { - actual := self.getView().Title - return expected.context(fmt.Sprintf("%s title", self.context)).test(actual) - }) - - return self +func (self *Views) Status() *View { + return self.ByName("status") } -// asserts that the view has lines matching the given matchers. So if three matchers -// are passed, we only check the first three lines of the view. -// This method is convenient when you have a list of commits but you only want to -// assert on the first couple of commits. -func (self *View) TopLines(matchers ...*matcher) *View { - self.assert.assertWithRetries(func() (bool, string) { - lines := self.getView().BufferLines() - return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines)) - }) - - return self.assertLines(matchers...) +func (self *Views) Submodules() *View { + return self.ByName("submodules") } -// 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. -func (self *View) Lines(matchers ...*matcher) *View { - self.assert.assertWithRetries(func() (bool, string) { - lines := self.getView().BufferLines() - return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines)) - }) - - return self.assertLines(matchers...) +func (self *Views) Information() *View { + return self.ByName("information") } -func (self *View) assertLines(matchers ...*matcher) *View { - view := self.getView() - - for i, matcher := range matchers { - checkIsSelected, matcher := matcher.checkIsSelected() - - self.assert.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()), - func() string { - return view.BufferLines()[i] - }, - ) - - if checkIsSelected { - self.assert.assertWithRetries(func() (bool, string) { - lineIdx := view.SelectedLineIdx() - return lineIdx == i, fmt.Sprintf("Unexpected selected line index in view '%s'. Expected %d, got %d", view.Name(), i, lineIdx) - }) - } - } - - return self +func (self *Views) Branches() *View { + return self.ByName("localBranches") } -// asserts on the content of the view i.e. the stuff within the view's frame. -func (self *View) Content(matcher *matcher) *View { - self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), - func() string { - return self.getView().Buffer() - }, - ) - - return self +func (self *Views) RemoteBranches() *View { + return self.ByName("remoteBranches") } -// asserts on the selected line of the view -func (self *View) SelectedLine(matcher *matcher) *View { - self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context), - func() string { - return self.getView().SelectedLine() - }, - ) - - return self +func (self *Views) Tags() *View { + return self.ByName("tags") } -// asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view. -func (self *View) SelectedLineIdx(expected int) *View { - self.assert.assertWithRetries(func() (bool, string) { - actual := self.getView().SelectedLineIdx() - return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual) - }) - - return self +func (self *Views) ReflogCommits() *View { + return self.ByName("reflogCommits") } -// func (self *View) Focus() *View { -// // we can easily change focus by switching to the view's window, but this assumes that the desired view -// // is at the top of that window. So for now we'll switch to the window then assert that the desired -// // view is on top (i.e. that it's the current view). -// whitelistedViewNames := []string{"status", "files", "localBranches", "commits", "stash"} +func (self *Views) SubCommits() *View { + return self.ByName("subCommits") +} -// viewName := self.getView().Name() +func (self *Views) CommitFiles() *View { + return self.ByName("commitFiles") +} -// if !lo.Contains(whitelistedViewNames, self.getView().Name()) { -// self.assert.fail(fmt.Sprintf("Cannot focus view %s: Focus() method not implemented", viewName)) -// } +func (self *Views) Stash() *View { + return self.ByName("stash") +} -// windowIndexMap := map[string]int{ -// "status": 0, -// "files": 1, -// "localBranches": 2, -// "commits": 3, -// "stash": 4, -// } +func (self *Views) Staging() *View { + return self.ByName("staging") +} -// self.input.switchToFilesWindow() -// self.press(self.keys.Universal.JumpToBlock[1]) -// self.assert.Views().Current().Name(viewName) +func (self *Views) StagingSecondary() *View { + return self.ByName("stagingSecondary") +} -// return self -// } +func (self *Views) Menu() *View { + return self.ByName("menu") +} + +func (self *Views) Confirmation() *View { + return self.ByName("confirmation") +} + +func (self *Views) CommitMessage() *View { + return self.ByName("commitMessage") +} + +func (self *Views) Suggestions() *View { + return self.ByName("suggestions") +} + +func (self *Views) MergeConflicts() *View { + return self.ByName("mergeConflicts") +} diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index dfe2b6aaa..131672654 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -17,54 +17,55 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { markCommitAsBad := func() { - input.Press(keys.Commits.ViewBisectOptions) - input.Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as bad`)).Confirm() + input.Views().Commits(). + Press(keys.Commits.ViewBisectOptions) + + input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as bad`)).Confirm() } markCommitAsGood := func() { - input.Press(keys.Commits.ViewBisectOptions) - input.Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() + input.Views().Commits(). + Press(keys.Commits.ViewBisectOptions) + + input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() } - assert.Model().AtLeastOneCommit() + input.Model().AtLeastOneCommit() - input.SwitchToCommitsView() - - assert.Views().Current().SelectedLine(Contains("commit 10")) - - input.NavigateToListItem(Contains("commit 09")) + input.Views().Commits(). + Focus(). + SelectedLine(Contains("commit 10")). + NavigateToListItem(Contains("commit 09")) markCommitAsBad() - assert.Views().ByName("information").Content(Contains("bisecting")) + input.Views().Information().Content(Contains("bisecting")) - assert.Views().Current().Name("commits").SelectedLine(Contains("<-- bad")) - - input.NavigateToListItem(Contains("commit 02")) + input.Views().Commits(). + IsFocused(). + SelectedLine(Contains("<-- bad")). + NavigateToListItem(Contains("commit 02")) markCommitAsGood() // lazygit will land us in the commit between our good and bad commits. - assert.Views().Current(). - Name("commits"). + input.Views().Commits().IsFocused(). SelectedLine(Contains("commit 05").Contains("<-- current")) markCommitAsBad() - assert.Views().Current(). - Name("commits"). + input.Views().Commits().IsFocused(). SelectedLine(Contains("commit 04").Contains("<-- current")) markCommitAsGood() // commit 5 is the culprit because we marked 4 as good and 5 as bad. - input.Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() + input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() - assert.Views().Current().Name("commits").Content(Contains("commit 04")) - assert.Views().ByName("information").Content(DoesNotContain("bisecting")) + input.Views().Commits().IsFocused().Content(Contains("commit 04")) + input.Views().Information().Content(DoesNotContain("bisecting")) }, }) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 0caab5d67..0112d7da5 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -21,33 +21,31 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { - assert.Views().ByName("information").Content(Contains("bisecting")) + input.Views().Information().Content(Contains("bisecting")) - assert.Model().AtLeastOneCommit() + input.Model().AtLeastOneCommit() - input.SwitchToCommitsView() + input.Views().Commits(). + Focus(). + TopLines( + MatchesRegexp(`<-- bad.*commit 08`), + MatchesRegexp(`<-- current.*commit 07`), + MatchesRegexp(`\?.*commit 06`), + MatchesRegexp(`<-- good.*commit 05`), + ). + SelectNextItem(). + Press(keys.Commits.ViewBisectOptions) - assert.Views().Current().TopLines( - MatchesRegexp(`<-- bad.*commit 08`), - MatchesRegexp(`<-- current.*commit 07`), - MatchesRegexp(`\?.*commit 06`), - MatchesRegexp(`<-- good.*commit 05`), - ) + input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() - input.NextItem() + input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() - input.Press(keys.Commits.ViewBisectOptions) - input.Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() - - input.Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() - - assert.Views().ByName("information").Content(DoesNotContain("bisecting")) + input.Views().Information().Content(DoesNotContain("bisecting")) // back in master branch which just had the one commit - assert.Views().Current().Name("commits").Lines( + input.Views().Commits().Lines( Contains("only commit on master"), ) }, diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index ccf75a831..59e810dec 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -17,22 +17,21 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ Checkout("master"). EmptyCommit("blah") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + Lines( + Contains("master"), + Contains("@"), + ). + SelectNextItem(). + Press(keys.Branches.CheckoutBranchByName) - assert.Views().Current().Lines( - Contains("master"), - Contains("@"), - ) - input.NextItem() + input.ExpectPrompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() - input.Press(keys.Branches.CheckoutBranchByName) + input.ExpectAlert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() - input.Prompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() - - input.Alert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() - - assert.Views().Current().Name("localBranches"). + input.Views().Branches().IsFocused(). Lines( MatchesRegexp(`\*.*new-branch`), Contains("master"), diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 08b4e8f62..eba3a016f 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -16,27 +16,28 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ NewBranch("branch-one"). NewBranch("branch-two") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + Lines( + MatchesRegexp(`\*.*branch-two`).IsSelected(), + MatchesRegexp(`branch-one`), + MatchesRegexp(`master`), + ). + Press(keys.Universal.Remove) - assert.Views().Current().Lines( - MatchesRegexp(`\*.*branch-two`), - MatchesRegexp(`branch-one`), - MatchesRegexp(`master`), - ) + input.ExpectAlert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() - input.Press(keys.Universal.Remove) - input.Alert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() + input.Views().Branches(). + SelectNextItem(). + Press(keys.Universal.Remove) - input.NextItem() - - input.Press(keys.Universal.Remove) - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Delete Branch")). Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). Confirm() - assert.Views().Current().Name("localBranches"). + input.Views().Branches().IsFocused(). Lines( MatchesRegexp(`\*.*branch-two`), MatchesRegexp(`master`).IsSelected(), diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index ab3302068..541493458 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -14,51 +14,51 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() - - assert.Views().ByName("localBranches").Lines( - Contains("first-change-branch"), - Contains("second-change-branch"), - Contains("original-branch"), - ) - - assert.Views().ByName("commits").TopLines( + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Commits().TopLines( Contains("first change"), Contains("original"), ) - input.NextItem() - input.Press(keys.Branches.RebaseBranch) + input.Views().Branches(). + Focus(). + Lines( + Contains("first-change-branch"), + Contains("second-change-branch"), + Contains("original-branch"), + ). + SelectNextItem(). + Press(keys.Branches.RebaseBranch) - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - input.Confirmation(). + + input.ExpectConfirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() - assert.Views().Current().Name("files").SelectedLine(Contains("file")) + input.Views().Files(). + IsFocused(). + SelectedLine(Contains("file")). + PressEnter() - // not using Confirm() convenience method because I suspect we might change this - // keybinding to something more bespoke - input.Press(keys.Universal.Confirm) + input.Views().MergeConflicts(). + IsFocused(). + PressPrimaryAction() - assert.Views().Current().Name("mergeConflicts") - input.PrimaryAction() + input.Views().Information().Content(Contains("rebasing")) - assert.Views().ByName("information").Content(Contains("rebasing")) - - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - assert.Views().ByName("information").Content(DoesNotContain("rebasing")) + input.Views().Information().Content(DoesNotContain("rebasing")) - assert.Views().ByName("commits").TopLines( + input.Views().Commits().TopLines( Contains("second-change-branch unrelated change"), Contains("second change"), Contains("original"), diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 1c77dbefc..53a718618 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -17,55 +17,51 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ shell.EmptyCommit("to remove") shell.EmptyCommit("to keep") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + Lines( + Contains("first-change-branch"), + Contains("second-change-branch"), + Contains("original-branch"), + ) - assert.Views().Current().Lines( - Contains("first-change-branch"), - Contains("second-change-branch"), - Contains("original-branch"), - ) + input.Views().Commits(). + TopLines( + Contains("to keep").IsSelected(), + Contains("to remove"), + Contains("first change"), + Contains("original"), + ). + SelectNextItem(). + Press(keys.Branches.RebaseBranch) - assert.Views().ByName("commits").TopLines( - Contains("to keep").IsSelected(), - Contains("to remove"), - Contains("first change"), - Contains("original"), - ) - - input.NextItem() - input.Press(keys.Branches.RebaseBranch) - - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - assert.Views().ByName("information").Content(Contains("rebasing")) + input.Views().Information().Content(Contains("rebasing")) - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() - assert.Views().Current(). - Name("files"). + input.Views().Files().IsFocused(). SelectedLine(MatchesRegexp("UU.*file")) - input.SwitchToCommitsView() - assert.Views().Current(). + input.Views().Commits(). + Focus(). TopLines( MatchesRegexp(`pick.*to keep`).IsSelected(), MatchesRegexp(`pick.*to remove`), MatchesRegexp("YOU ARE HERE.*second-change-branch unrelated change"), MatchesRegexp("second change"), MatchesRegexp("original"), - ) - - input.NextItem() - input.Press(keys.Universal.Remove) - - assert.Views().Current(). + ). + SelectNextItem(). + Press(keys.Universal.Remove). TopLines( MatchesRegexp(`pick.*to keep`), MatchesRegexp(`drop.*to remove`).IsSelected(), @@ -74,23 +70,22 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ MatchesRegexp("original"), ) - input.SwitchToFilesView() + input.Views().Files(). + Focus(). + PressEnter() - // not using Confirm() convenience method because I suspect we might change this - // keybinding to something more bespoke - input.Press(keys.Universal.Confirm) + input.Views().MergeConflicts(). + IsFocused(). + PressPrimaryAction() - assert.Views().Current().Name("mergeConflicts") - input.PrimaryAction() - - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - assert.Views().ByName("information").Content(DoesNotContain("rebasing")) + input.Views().Information().Content(DoesNotContain("rebasing")) - assert.Views().ByName("commits").TopLines( + input.Views().Commits().TopLines( Contains("to keep"), Contains("second-change-branch unrelated change").IsSelected(), Contains("second change"), diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index fec6aea7a..fc5bbebf0 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -20,32 +20,31 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("current-branch") shell.EmptyCommit("current-branch commit") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Views().ByName("commits").Lines( + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Commits().Lines( Contains("current-branch commit"), Contains("root commit"), ) - input.SwitchToBranchesView() + input.Views().Branches(). + Focus(). + Lines( + Contains("current-branch"), + Contains("other-branch"), + ). + SelectNextItem(). + Press(keys.Commits.ViewResetOptions) - assert.Views().Current().Lines( - Contains("current-branch"), - Contains("other-branch"), - ) - input.NextItem() - - input.Press(keys.Commits.ViewResetOptions) - - input.Menu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() + input.ExpectMenu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() // ensure that we've returned from the menu before continuing - assert.Views().Current().Name("localBranches") + input.Views().Branches().IsFocused() // assert that we now have the expected commits in the commit panel - input.SwitchToCommitsView() - assert.Views().Current().Lines( - Contains("other-branch commit"), - Contains("root commit"), - ) + input.Views().Commits(). + Lines( + Contains("other-branch commit"), + Contains("root commit"), + ) }, }) diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index b33a78721..9999947d9 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -20,20 +20,20 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ NewBranch("other-new-branch-2"). NewBranch("other-new-branch-3") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() - - input.Press(keys.Branches.CheckoutBranchByName) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + Press(keys.Branches.CheckoutBranchByName) // we expect the first suggestion to be the branch we want because it most // closely matches what we typed in - input.Prompt(). + input.ExpectPrompt(). Title(Equals("Branch name:")). Type("branch-to"). SuggestionTopLines(Contains("branch-to-checkout")). SelectFirstSuggestion(). Confirm() - assert.Model().CurrentBranchName("branch-to-checkout") + input.Model().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 f832bfe83..75c060b34 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -23,56 +23,65 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("four"). Checkout("first-branch") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + Lines( + Contains("first-branch"), + Contains("second-branch"), + Contains("master"), + ). + SelectNextItem(). + PressEnter() - assert.Views().Current().Lines( - Contains("first-branch"), - Contains("second-branch"), - Contains("master"), - ) + input.Views().SubCommits(). + IsFocused(). + Lines( + Contains("four").IsSelected(), + Contains("three"), + Contains("base"), + ). + // copy commits 'four' and 'three' + Press(keys.Commits.CherryPickCopy) - input.NextItem() + input.Views().Information().Content(Contains("1 commit copied")) - input.Enter() + input.Views().SubCommits(). + SelectNextItem(). + Press(keys.Commits.CherryPickCopy) - assert.Views().Current().Name("subCommits").Lines( - Contains("four"), - Contains("three"), - Contains("base"), - ) + input.Views().Information().Content(Contains("2 commits copied")) - // copy commits 'four' and 'three' - input.Press(keys.Commits.CherryPickCopy) - assert.Views().ByName("information").Content(Contains("1 commit copied")) - input.NextItem() - input.Press(keys.Commits.CherryPickCopy) - assert.Views().ByName("information").Content(Contains("2 commits copied")) + input.Views().Commits(). + Focus(). + Lines( + Contains("two").IsSelected(), + Contains("one"), + Contains("base"), + ). + Press(keys.Commits.PasteCommits) - input.SwitchToCommitsView() - - assert.Views().Current().Lines( - Contains("two"), - Contains("one"), - Contains("base"), - ) - - input.Press(keys.Commits.PasteCommits) - input.Alert(). + input.ExpectAlert(). Title(Equals("Cherry-Pick")). Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). Confirm() - assert.Views().Current().Name("commits").Lines( - Contains("four"), - Contains("three"), - Contains("two"), - Contains("one"), - Contains("base"), - ) + input.Views().Commits(). + IsFocused(). + Lines( + Contains("four"), + Contains("three"), + Contains("two"), + Contains("one"), + Contains("base"), + ) - assert.Views().ByName("information").Content(Contains("2 commits copied")) - input.Press(keys.Universal.Return) - assert.Views().ByName("information").Content(DoesNotContain("commits copied")) + // we need to manually exit out of cherrry pick mode + input.Views().Information().Content(Contains("2 commits copied")) + + input.Views().Commits(). + PressEscape() + + input.Views().Information().Content(DoesNotContain("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 b078f7164..9b97be5db 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -14,81 +14,86 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() - assert.Views().Current().Lines( - Contains("first-change-branch"), - Contains("second-change-branch"), - Contains("original-branch"), - ) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + Lines( + Contains("first-change-branch"), + Contains("second-change-branch"), + Contains("original-branch"), + ). + SelectNextItem(). + PressEnter() - input.NextItem() + input.Views().SubCommits(). + IsFocused(). + TopLines( + Contains("second-change-branch unrelated change"), + Contains("second change"), + ). + Press(keys.Commits.CherryPickCopy) - input.Enter() + input.Views().Information().Content(Contains("1 commit copied")) - assert.Views().Current().Name("subCommits").TopLines( - Contains("second-change-branch unrelated change"), - Contains("second change"), - ) + input.Views().SubCommits(). + SelectNextItem(). + Press(keys.Commits.CherryPickCopy) - input.Press(keys.Commits.CherryPickCopy) - assert.Views().ByName("information").Content(Contains("1 commit copied")) + input.Views().Information().Content(Contains("2 commits copied")) - input.NextItem() - input.Press(keys.Commits.CherryPickCopy) - assert.Views().ByName("information").Content(Contains("2 commits copied")) + input.Views().Commits(). + Focus(). + TopLines( + Contains("first change"), + ). + Press(keys.Commits.PasteCommits) - input.SwitchToCommitsView() + input.ExpectAlert().Title(Equals("Cherry-Pick")).Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).Confirm() - assert.Views().Current().TopLines( - Contains("first change"), - ) - - input.Press(keys.Commits.PasteCommits) - input.Alert().Title(Equals("Cherry-Pick")).Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).Confirm() - - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() - assert.Views().Current().Name("files") - assert.Views().Current().SelectedLine(Contains("file")) + input.Views().Files(). + IsFocused(). + SelectedLine(Contains("file")). + PressEnter() - // not using Confirm() convenience method because I suspect we might change this - // keybinding to something more bespoke - input.Press(keys.Universal.Confirm) + input.Views().MergeConflicts(). + IsFocused(). + // picking 'Second change' + SelectNextItem(). + PressPrimaryAction() - assert.Views().Current().Name("mergeConflicts") - // picking 'Second change' - input.NextItem() - input.PrimaryAction() - - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - assert.Views().Current().Name("files") - assert.Model().WorkingTreeFileCount(0) + input.Model().WorkingTreeFileCount(0) - input.SwitchToCommitsView() + input.Views().Commits(). + Focus(). + TopLines( + Contains("second-change-branch unrelated change"), + Contains("second change"), + Contains("first change"), + ). + SelectNextItem() - assert.Views().Current().TopLines( - Contains("second-change-branch unrelated change"), - Contains("second change"), - Contains("first change"), - ) - input.NextItem() // because we picked 'Second change' when resolving the conflict, // we now see this commit as having replaced First Change with Second Change, // as opposed to replacing 'Original' with 'Second change' - assert.Views().Main(). + input.Views().Main(). Content(Contains("-First Change")). Content(Contains("+Second Change")) - assert.Views().ByName("information").Content(Contains("2 commits copied")) - input.Press(keys.Universal.Return) - assert.Views().ByName("information").Content(DoesNotContain("commits copied")) + input.Views().Information().Content(Contains("2 commits copied")) + + input.Views().Commits(). + PressEscape() + + input.Views().Information().Content(DoesNotContain("commits copied")) }, }) diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index 93ccf5b53..acd31e4e7 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -14,19 +14,21 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("myfile", "myfile content") shell.CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(0) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(0) - input.PrimaryAction() - input.NextItem() - input.PrimaryAction() - input.Press(keys.Files.CommitChanges) + input.Views().Files(). + IsFocused(). + PressPrimaryAction(). // stage file + SelectNextItem(). + PressPrimaryAction(). // stage other file + Press(keys.Files.CommitChanges) commitMessage := "my commit message" - input.CommitMessagePanel().Type(commitMessage).Confirm() + input.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - assert.Model().CommitCount(1) - assert.Model().HeadCommitMessage(Equals(commitMessage)) + input.Model().CommitCount(1) + input.Model().HeadCommitMessage(Equals(commitMessage)) }, }) diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index 3beeff344..4f80adbe1 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -13,18 +13,20 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shell.CreateFile("myfile", "myfile content") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(0) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(0) - input.PrimaryAction() - input.Press(keys.Files.CommitChanges) + input.Views().Files(). + IsFocused(). + PressPrimaryAction(). + Press(keys.Files.CommitChanges) - input.CommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() + input.ExpectCommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() - assert.Model().CommitCount(1) - assert.Model().HeadCommitMessage(Equals("first line")) + input.Model().CommitCount(1) + input.Model().HeadCommitMessage(Equals("first line")) - input.SwitchToCommitsView() - assert.Views().Main().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) + input.Views().Commits().Focus() + input.Views().Main().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) }, }) diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index c02ffb9a9..cd194593b 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -16,25 +16,25 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("commit 2"). EmptyCommit("commit 3") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(3) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(3) - input.SwitchToCommitsView() - assert.Views().Current().Lines( - Contains("commit 3"), - Contains("commit 2"), - Contains("commit 1"), - ) - input.NextItem() - - input.Press(keys.Universal.New) + input.Views().Commits(). + Focus(). + Lines( + Contains("commit 3"), + Contains("commit 2"), + Contains("commit 1"), + ). + SelectNextItem(). + Press(keys.Universal.New) branchName := "my-branch-name" - input.Prompt().Title(Equals("New Branch Name")).Type(branchName).Confirm() + input.ExpectPrompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() - assert.Model().CurrentBranchName(branchName) + input.Model().CurrentBranchName(branchName) - assert.Views().ByName("commits").Lines( + input.Views().Commits().Lines( Contains("commit 2"), Contains("commit 1"), ) diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index ca1a94be5..24de24e34 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -15,28 +15,28 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ shell.GitAddAll() shell.Commit("first commit") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(1) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(1) - input.SwitchToCommitsView() + input.Views().Commits(). + Focus(). + Lines( + Contains("first commit"), + ). + Press(keys.Commits.RevertCommit) - assert.Views().Current().Lines( - Contains("first commit"), - ) - - input.Press(keys.Commits.RevertCommit) - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Revert commit")). Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). Confirm() - assert.Views().Current().Name("commits"). + input.Views().Commits().IsFocused(). Lines( Contains("Revert \"first commit\"").IsSelected(), Contains("first commit"), ) - assert.Views().Main().Content(Contains("-myfile content")) - assert.FileSystem().PathNotPresent("myfile") + input.Views().Main().Content(Contains("-myfile content")) + input.FileSystem().PathNotPresent("myfile") }, }) diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index ffcd7dd9b..8919ab852 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -15,38 +15,41 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(0) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(0) - assert.Views().Current().Name("files") - assert.Views().Current().SelectedLine(Contains("myfile")) - // stage the file - input.PrimaryAction() - input.Enter() - assert.Views().Current().Name("stagingSecondary") + input.Views().Files(). + IsFocused(). + SelectedLine(Contains("myfile")). + PressPrimaryAction(). // stage the file + PressEnter() + + input.Views().StagingSecondary().IsFocused() // we start with both lines having been staged - assert.Views().ByName("stagingSecondary").Content(Contains("+myfile content")) - assert.Views().ByName("stagingSecondary").Content(Contains("+with a second line")) - assert.Views().ByName("staging").Content(DoesNotContain("+myfile content")) - assert.Views().ByName("staging").Content(DoesNotContain("+with a second line")) + input.Views().StagingSecondary().Content(Contains("+myfile content")) + input.Views().StagingSecondary().Content(Contains("+with a second line")) + input.Views().Staging().Content(DoesNotContain("+myfile content")) + input.Views().Staging().Content(DoesNotContain("+with a second line")) // unstage the selected line - input.PrimaryAction() + input.Views().StagingSecondary(). + PressPrimaryAction() // the line should have been moved to the main view - assert.Views().ByName("stagingSecondary").Content(DoesNotContain("+myfile content")) - assert.Views().ByName("stagingSecondary").Content(Contains("+with a second line")) - assert.Views().ByName("staging").Content(Contains("+myfile content")) - assert.Views().ByName("staging").Content(DoesNotContain("+with a second line")) + input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) + input.Views().StagingSecondary().Content(Contains("+with a second line")) + input.Views().Staging().Content(Contains("+myfile content")) + input.Views().Staging().Content(DoesNotContain("+with a second line")) + + input.Views().StagingSecondary(). + Press(keys.Files.CommitChanges) - input.Press(keys.Files.CommitChanges) commitMessage := "my commit message" - input.Type(commitMessage) - input.Confirm() + input.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - assert.Model().CommitCount(1) - assert.Model().HeadCommitMessage(Equals(commitMessage)) - assert.Views().Current().Name("stagingSecondary") + input.Model().CommitCount(1) + input.Model().HeadCommitMessage(Equals(commitMessage)) + input.Views().StagingSecondary().IsFocused() // 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 9d1dcb97d..d77602d51 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -15,38 +15,41 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(0) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(0) // stage the file - assert.Views().Current().Name("files") - assert.Views().Current().SelectedLine(Contains("myfile")) - input.PrimaryAction() - input.Enter() - assert.Views().Current().Name("stagingSecondary") + input.Views().Files(). + IsFocused(). + SelectedLine(Contains("myfile")). + PressPrimaryAction(). + PressEnter() + // we start with both lines having been staged - assert.Views().ByName("stagingSecondary").Content( + input.Views().StagingSecondary().Content( Contains("+myfile content").Contains("+with a second line"), ) - assert.Views().ByName("staging").Content( + input.Views().Staging().Content( DoesNotContain("+myfile content").DoesNotContain("+with a second line"), ) // unstage the selected line - input.PrimaryAction() + input.Views().StagingSecondary(). + IsFocused(). + PressPrimaryAction() // the line should have been moved to the main view - assert.Views().ByName("stagingSecondary").Content(DoesNotContain("+myfile content").Contains("+with a second line")) - assert.Views().ByName("staging").Content(Contains("+myfile content").DoesNotContain("+with a second line")) - - input.Press(keys.Files.CommitChangesWithoutHook) + input.Views().Staging().Content(Contains("+myfile content").DoesNotContain("+with a second line")) + input.Views().StagingSecondary(). + Content(DoesNotContain("+myfile content").Contains("+with a second line")). + Press(keys.Files.CommitChangesWithoutHook) commitMessage := ": my commit message" - input.CommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() + input.ExpectCommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() - assert.Model().CommitCount(1) - assert.Model().HeadCommitMessage(Equals("WIP" + commitMessage)) - assert.Views().Current().Name("stagingSecondary") + input.Model().CommitCount(1) + input.Model().HeadCommitMessage(Equals("WIP" + commitMessage)) + input.Views().StagingSecondary().IsFocused() // 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 e8c8126e0..ea08b8462 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -5,7 +5,7 @@ import ( . "github.com/jesseduffield/lazygit/pkg/integration/components" ) -// TODO: find out why we can't use assert.SelectedLine() on the staging/stagingSecondary views. +// TODO: find out why we can't use input.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", @@ -17,26 +17,35 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(0) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(0) + + input.Views().Files(). + IsFocused(). + SelectedLine(Contains("myfile")). + PressEnter() + + input.Views().Staging(). + IsFocused() + + input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) - assert.Views().Current().Name("files").SelectedLine(Contains("myfile")) - input.Enter() - assert.Views().Current().Name("staging") - assert.Views().ByName("stagingSecondary").Content(DoesNotContain("+myfile content")) // stage the first line - input.PrimaryAction() - assert.Views().ByName("staging").Content(DoesNotContain("+myfile content")) - assert.Views().ByName("stagingSecondary").Content(Contains("+myfile content")) + input.Views().Staging(). + PressPrimaryAction() - input.Press(keys.Files.CommitChanges) + input.Views().Staging().Content(DoesNotContain("+myfile content")) + input.Views().StagingSecondary().Content(Contains("+myfile content")) + + input.Views().Staging(). + Press(keys.Files.CommitChanges) commitMessage := "my commit message" - input.CommitMessagePanel().Type(commitMessage).Confirm() + input.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - assert.Model().CommitCount(1) - assert.Model().HeadCommitMessage(Equals(commitMessage)) - assert.Views().Current().Name("staging") + input.Model().CommitCount(1) + input.Model().HeadCommitMessage(Equals(commitMessage)) + input.Views().Staging().IsFocused() // TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed) }, diff --git a/pkg/integration/tests/config/remote_named_star.go b/pkg/integration/tests/config/remote_named_star.go index 589394061..1796cab20 100644 --- a/pkg/integration/tests/config/remote_named_star.go +++ b/pkg/integration/tests/config/remote_named_star.go @@ -18,10 +18,9 @@ var RemoteNamedStar = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { // here we're just asserting that we haven't panicked upon starting lazygit - assert.Model().AtLeastOneCommit() + input.Model().AtLeastOneCommit() }, }) diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go index bd7b1519b..2317525ac 100644 --- a/pkg/integration/tests/custom_commands/basic.go +++ b/pkg/integration/tests/custom_commands/basic.go @@ -24,15 +24,15 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { - assert.Model().WorkingTreeFileCount(0) + input.Model().WorkingTreeFileCount(0) - input.Press("a") - - assert.Views().ByName("files").Lines( - Contains("myfile"), - ) + input.Views().Files(). + IsFocused(). + Press("a"). + Lines( + Contains("myfile"), + ) }, }) diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index cc854d524..e07f57450 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -58,24 +58,25 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { - assert.Model().WorkingTreeFileCount(0) + input.Model().WorkingTreeFileCount(0) - input.Press("a") + input.Views().Files(). + IsFocused(). + Press("a") - input.Prompt().Title(Equals("Enter a file name")).Type("my file").Confirm() + input.ExpectPrompt().Title(Equals("Enter a file name")).Type("my file").Confirm() - input.Menu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() + input.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - assert.Model().WorkingTreeFileCount(1) - assert.Views().Current().SelectedLine(Contains("my file")) - assert.Views().Main().Content(Contains(`"BAR"`)) + input.Model().WorkingTreeFileCount(1) + input.Views().Files().SelectedLine(Contains("my file")) + input.Views().Main().Content(Contains(`"BAR"`)) }, }) diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index a89b4e90a..6af2a663f 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -45,22 +45,20 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { - assert.Model().WorkingTreeFileCount(0) - input.SwitchToBranchesView() + input.Model().WorkingTreeFileCount(0) + input.Views().Branches(). + Focus(). + Press("a") - input.Press("a") + input.ExpectMenu().Title(Equals("Choose commit message")).Select(Contains("bar")).Confirm() - input.Menu().Title(Equals("Choose commit message")).Select(Contains("bar")).Confirm() + input.ExpectPrompt().Title(Equals("Description")).Type(" my branch").Confirm() - input.Prompt().Title(Equals("Description")).Type(" my branch").Confirm() + input.Model().WorkingTreeFileCount(1) - input.SwitchToFilesView() - - assert.Model().WorkingTreeFileCount(1) - assert.Views().Current().SelectedLine(Contains("output.txt")) - assert.Views().Main().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) + input.Views().Files().Focus().SelectedLine(Contains("output.txt")) + input.Views().Main().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) }, }) 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 e17f38cdd..2877ab006 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -44,23 +44,22 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { - assert.Model().CurrentBranchName("feature/bar") + input.Model().CurrentBranchName("feature/bar") + input.Model().WorkingTreeFileCount(0) - assert.Model().WorkingTreeFileCount(0) - input.SwitchToBranchesView() + input.Views().Branches(). + Focus(). + Press("a") - input.Press("a") - - input.Prompt(). + input.ExpectPrompt(). Title(Equals("Which git command do you want to run?")). InitialText(Equals("branch")). Confirm() - input.Menu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() + input.ExpectMenu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() - assert.Model().CurrentBranchName("master") + input.Model().CurrentBranchName("master") }, }) diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index c3f040e27..4f94cb28d 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -56,24 +56,25 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ Run: func( shell *Shell, input *Input, - assert *Assert, keys config.KeybindingConfig, ) { - assert.Model().WorkingTreeFileCount(0) + input.Model().WorkingTreeFileCount(0) - input.Press("a") + input.Views().Files(). + IsFocused(). + Press("a") - input.Prompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() + input.ExpectPrompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() - input.Menu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() + input.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - assert.Model().WorkingTreeFileCount(1) - assert.Views().Current().SelectedLine(Contains("myfile")) - assert.Views().Main().Content(Contains("BAR")) + input.Model().WorkingTreeFileCount(1) + input.Views().Files().SelectedLine(Contains("myfile")) + input.Views().Main().Content(Contains("BAR")) }, }) diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index 96484b421..d940b8c20 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -21,38 +21,55 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("branch-a") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + TopLines( + Contains("branch-a"), + Contains("branch-b"), + ). + Press(keys.Universal.DiffingMenu) - assert.Views().Current().TopLines( - Contains("branch-a"), - Contains("branch-b"), - ) - input.Press(keys.Universal.DiffingMenu) - input.Menu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() + input.ExpectMenu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() - assert.Views().Current().Name("localBranches") + input.Views().Branches(). + IsFocused() - assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-a")) - input.NextItem() - assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-b")) - assert.Views().Main().Content(Contains("+second line")) + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) - input.Enter() - assert.Views().Current().Name("subCommits") - assert.Views().Main().Content(Contains("+second line")) - assert.Views().Current().SelectedLine(Contains("update")) - input.Enter() - assert.Views().Current().Name("commitFiles").SelectedLine(Contains("file1")) - assert.Views().Main().Content(Contains("+second line")) + input.Views().Branches(). + SelectNextItem() - input.Press(keys.Universal.Return) - input.Press(keys.Universal.Return) - assert.Views().Current().Name("localBranches") + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) + input.Views().Main().Content(Contains("+second line")) - input.Press(keys.Universal.DiffingMenu) - input.Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-b -R")) - assert.Views().Main().Content(Contains("-second line")) + input.Views().Branches(). + PressEnter() + + input.Views().SubCommits(). + IsFocused(). + SelectedLine(Contains("update")) + + input.Views().Main().Content(Contains("+second line")) + + input.Views().SubCommits(). + PressEnter() + + input.Views().CommitFiles(). + IsFocused(). + SelectedLine(Contains("file1")) + + input.Views().Main().Content(Contains("+second line")) + + input.Views().CommitFiles().PressEscape() + input.Views().SubCommits().PressEscape() + + input.Views().Branches(). + IsFocused(). + Press(keys.Universal.DiffingMenu) + + input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b -R")) + input.Views().Main().Content(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 fdcaf0be7..3d78e1c55 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -21,48 +21,62 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("branch-a") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToBranchesView() - assert.Views().Current().Lines( - Contains("branch-a"), - Contains("branch-b"), - ) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Branches(). + Focus(). + Lines( + Contains("branch-a"), + Contains("branch-b"), + ). + Press(keys.Universal.DiffingMenu) - input.Press(keys.Universal.DiffingMenu) + input.ExpectMenu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() - input.Menu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) - assert.Views().Current().Name("localBranches") + input.Views().Branches(). + IsFocused(). + SelectNextItem() - assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-a")) - input.NextItem() - assert.Views().ByName("information").Content(Contains("showing output for: git diff branch-a branch-b")) - assert.Views().Main().Content(Contains("+second line")) + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) + input.Views().Main().Content(Contains("+second line")) - input.Enter() - assert.Views().Current().Name("subCommits") - assert.Views().Main().Content(Contains("+second line")) - assert.Views().Current().SelectedLine(Contains("update")) - input.Enter() - assert.Views().Current().Name("commitFiles") - assert.Views().Current().SelectedLine(Contains("file1")) - assert.Views().Main().Content(Contains("+second line")) + input.Views().Branches(). + PressEnter() - // add the file to the patch - input.PrimaryAction() + input.Views().SubCommits(). + IsFocused(). + SelectedLine(Contains("update")) - input.Press(keys.Universal.DiffingMenu) - input.Menu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() + input.Views().Main().Content(Contains("+second line")) - assert.Views().ByName("information").Content(DoesNotContain("building patch")) + input.Views().SubCommits(). + PressEnter() + + input.Views().CommitFiles(). + IsFocused(). + SelectedLine(Contains("file1")) + + input.Views().Main().Content(Contains("+second line")) + + input.Views().CommitFiles(). + PressPrimaryAction(). // add the file to the patch + Press(keys.Universal.DiffingMenu) + + input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() + + input.Views().Information().Content(DoesNotContain("building patch")) + + input.Views().CommitFiles(). + Press(keys.Universal.CreatePatchOptionsMenu) - input.Press(keys.Universal.CreatePatchOptionsMenu) // adding the regex '$' here to distinguish the menu item from the 'apply patch in reverse' item - input.Menu().Title(Equals("Patch Options")).Select(MatchesRegexp("apply patch$")).Confirm() + input.ExpectMenu().Title(Equals("Patch Options")).Select(MatchesRegexp("apply patch$")).Confirm() - input.SwitchToFilesView() + input.Views().Files(). + Focus(). + SelectedLine(Contains("file1")) - assert.Views().Current().SelectedLine(Contains("file1")) - assert.Views().Main().Content(Contains("+second line")) + input.Views().Main().Content(Contains("+second line")) }, }) diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index d05272e07..9b05cc582 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -18,34 +18,41 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ shell.UpdateFileAndAdd("file1", "first line\nsecond line\nthird line\n") shell.Commit("third commit") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToCommitsView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Commits(). + Focus(). + Lines( + Contains("third commit"), + Contains("second commit"), + Contains("first commit"), + ). + Press(keys.Universal.DiffingMenu) - assert.Views().Current().Lines( - Contains("third commit"), - Contains("second commit"), - Contains("first commit"), - ) + input.ExpectMenu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() - input.Press(keys.Universal.DiffingMenu) - input.Menu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() + input.Views().Information().Content(Contains("showing output for: git diff")) - assert.Views().ByName("information").Content(Contains("showing output for: git diff")) + input.Views().Commits(). + SelectNextItem(). + SelectNextItem(). + SelectedLine(Contains("first commit")) - input.NextItem() - input.NextItem() - assert.Views().Current().SelectedLine(Contains("first commit")) + input.Views().Main().Content(Contains("-second line\n-third line")) - assert.Views().Main().Content(Contains("-second line\n-third line")) + input.Views().Commits(). + Press(keys.Universal.DiffingMenu) - input.Press(keys.Universal.DiffingMenu) - input.Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() + input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - assert.Views().Main().Content(Contains("+second line\n+third line")) + input.Views().Main().Content(Contains("+second line\n+third line")) - input.Enter() + input.Views().Commits(). + PressEnter() - assert.Views().Current().Name("commitFiles").SelectedLine(Contains("file1")) - assert.Views().Main().Content(Contains("+second line\n+third line")) + input.Views().CommitFiles(). + IsFocused(). + SelectedLine(Contains("file1")) + + input.Views().Main().Content(Contains("+second line\n+third line")) }, }) diff --git a/pkg/integration/tests/file/dir_with_untracked_file.go b/pkg/integration/tests/file/dir_with_untracked_file.go index bfd40f2ea..be0e7022e 100644 --- a/pkg/integration/tests/file/dir_with_untracked_file.go +++ b/pkg/integration/tests/file/dir_with_untracked_file.go @@ -21,10 +21,10 @@ var DirWithUntrackedFile = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("dir/untracked", "bar") shell.UpdateFile("dir/file", "baz") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(1) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(1) - assert.Views().Main(). + input.Views().Main(). Content(DoesNotContain("error: Could not access")). // we show baz because it's a modified file but we don't show bar because it's untracked // (though it would be cool if we could show that too) diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index cb650f34d..b36b9a0ab 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -71,8 +71,8 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ shell.RunShellCommand(`echo "renamed\nhaha" > renamed2.txt && git add renamed2.txt`) }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(3) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(3) type statusFile struct { status string @@ -82,9 +82,12 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ discardOneByOne := func(files []statusFile) { for _, file := range files { - assert.Views().Current().SelectedLine(Contains(file.status + " " + file.label)) - input.Press(keys.Universal.Remove) - input.Menu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() + input.Views().Files(). + IsFocused(). + SelectedLine(Contains(file.status + " " + file.label)). + Press(keys.Universal.Remove) + + input.ExpectMenu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() } } @@ -98,7 +101,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"}, }) - input.Confirmation(). + input.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Cancel() @@ -118,6 +121,6 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "??", label: "new.txt", menuTitle: "new.txt"}, }) - assert.Model().WorkingTreeFileCount(0) + input.Model().WorkingTreeFileCount(0) }, }) diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 6bfbdb4db..8fcb850c6 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -27,26 +27,27 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ Merge("feature-branch"). CreateFileAndAdd(postMergeFilename, postMergeFileContent) }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(3) - - input.SwitchToCommitsView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(3) mergeCommitMessage := "Merge branch 'feature-branch' into development-branch" - assert.Model().HeadCommitMessage(Contains(mergeCommitMessage)) + input.Model().HeadCommitMessage(Contains(mergeCommitMessage)) - input.Press(keys.Commits.AmendToCommit) - input.Confirmation(). + input.Views().Commits(). + Focus(). + Press(keys.Commits.AmendToCommit) + + input.ExpectConfirmation(). Title(Equals("Amend Commit")). Content(Contains("Are you sure you want to amend this commit with your staged files?")). Confirm() // assuring we haven't added a brand new commit - assert.Model().CommitCount(3) - assert.Model().HeadCommitMessage(Contains(mergeCommitMessage)) + input.Model().CommitCount(3) + input.Model().HeadCommitMessage(Contains(mergeCommitMessage)) // assuring the post-merge file shows up in the merge commit. - assert.Views().Main(). + input.Views().Main(). Content(Contains(postMergeFilename)). Content(Contains("++" + postMergeFileContent)) }, diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go index 170bcf364..eec707ecc 100644 --- a/pkg/integration/tests/interactive_rebase/one.go +++ b/pkg/integration/tests/interactive_rebase/one.go @@ -14,61 +14,56 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ shell. CreateNCommits(5) // these will appears at commit 05, 04, 04, down to 01 }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToCommitsView() - assert.Views().Current().Lines( - Contains("commit 05"), - Contains("commit 04"), - Contains("commit 03"), - Contains("commit 02"), - Contains("commit 01"), - ) - - input.NavigateToListItem(Contains("commit 02")) - input.Press(keys.Universal.Edit) - - assert.Views().Current().Lines( - MatchesRegexp("pick.*commit 05"), - MatchesRegexp("pick.*commit 04"), - MatchesRegexp("pick.*commit 03"), - MatchesRegexp("YOU ARE HERE.*commit 02"), - Contains("commit 01"), - ) - - input.PreviousItem() - input.Press(keys.Commits.MarkCommitAsFixup) - assert.Views().Current().Lines( - MatchesRegexp("pick.*commit 05"), - MatchesRegexp("pick.*commit 04"), - MatchesRegexp("fixup.*commit 03"), - MatchesRegexp("YOU ARE HERE.*commit 02"), - Contains("commit 01"), - ) - - input.PreviousItem() - input.Press(keys.Universal.Remove) - assert.Views().Current().Lines( - MatchesRegexp("pick.*commit 05"), - MatchesRegexp("drop.*commit 04"), - MatchesRegexp("fixup.*commit 03"), - MatchesRegexp("YOU ARE HERE.*commit 02"), - Contains("commit 01"), - ) - - input.PreviousItem() - input.Press(keys.Commits.SquashDown) - - assert.Views().Current().Lines( - MatchesRegexp("squash.*commit 05"), - MatchesRegexp("drop.*commit 04"), - MatchesRegexp("fixup.*commit 03"), - MatchesRegexp("YOU ARE HERE.*commit 02"), - Contains("commit 01"), - ) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Commits(). + Focus(). + Lines( + Contains("commit 05"), + Contains("commit 04"), + Contains("commit 03"), + Contains("commit 02"), + Contains("commit 01"), + ). + NavigateToListItem(Contains("commit 02")). + Press(keys.Universal.Edit). + Lines( + MatchesRegexp("pick.*commit 05"), + MatchesRegexp("pick.*commit 04"), + MatchesRegexp("pick.*commit 03"), + MatchesRegexp("YOU ARE HERE.*commit 02").IsSelected(), + Contains("commit 01"), + ). + SelectPreviousItem(). + Press(keys.Commits.MarkCommitAsFixup). + Lines( + MatchesRegexp("pick.*commit 05"), + MatchesRegexp("pick.*commit 04"), + MatchesRegexp("fixup.*commit 03").IsSelected(), + MatchesRegexp("YOU ARE HERE.*commit 02"), + Contains("commit 01"), + ). + SelectPreviousItem(). + Press(keys.Universal.Remove). + Lines( + MatchesRegexp("pick.*commit 05"), + MatchesRegexp("drop.*commit 04").IsSelected(), + MatchesRegexp("fixup.*commit 03"), + MatchesRegexp("YOU ARE HERE.*commit 02"), + Contains("commit 01"), + ). + SelectPreviousItem(). + Press(keys.Commits.SquashDown). + Lines( + MatchesRegexp("squash.*commit 05").IsSelected(), + MatchesRegexp("drop.*commit 04"), + MatchesRegexp("fixup.*commit 03"), + MatchesRegexp("YOU ARE HERE.*commit 02"), + Contains("commit 01"), + ) input.ContinueRebase() - assert.Views().Current().Lines( + input.Views().Commits().Lines( Contains("commit 02"), Contains("commit 01"), ) diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index 4d12418c1..0cb833046 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -13,11 +13,14 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ config.UserConfig.ConfirmOnQuit = true }, SetupRepo: func(shell *Shell) {}, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().CommitCount(0) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().CommitCount(0) - input.Press(keys.Universal.Quit) - input.Confirmation(). + input.Views().Files(). + IsFocused(). + Press(keys.Universal.Quit) + + input.ExpectConfirmation(). Title(Equals("")). Content(Contains("Are you sure you want to quit?")). Confirm() diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index 443f64a14..48eae4a99 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -18,18 +18,18 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ CreateFileAndAdd("file-2", "change to stash2"). StashWithMessage("bar") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.SwitchToStashView() + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Views().Stash(). + Focus(). + Lines( + Equals("On master: bar"), + Equals("On master: foo"), + ). + SelectNextItem(). + Press(keys.Stash.RenameStash) - assert.Views().Current().Lines( - Equals("On master: bar"), - Equals("On master: foo"), - ) - input.NextItem() - input.Press(keys.Stash.RenameStash) + input.ExpectPrompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() - input.Prompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() - - assert.Views().Current().SelectedLine(Equals("On master: foo baz")) + input.Views().Stash().SelectedLine(Equals("On master: foo baz")) }, }) diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index e506b150a..34e376886 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -15,17 +15,18 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("file", "content") shell.GitAddAll() }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().StashCount(0) - assert.Model().WorkingTreeFileCount(1) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().StashCount(0) + input.Model().WorkingTreeFileCount(1) - input.Press(keys.Files.ViewStashOptions) + input.Views().Files(). + Press(keys.Files.ViewStashOptions) - input.Menu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() + input.ExpectMenu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() - input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() + input.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - assert.Model().StashCount(1) - assert.Model().WorkingTreeFileCount(0) + input.Model().StashCount(1) + input.Model().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 673bb1c04..d923aca3a 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -16,17 +16,18 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("file_2", "content") shell.GitAdd("file_1") }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.Model().StashCount(0) - assert.Model().WorkingTreeFileCount(2) + Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { + input.Model().StashCount(0) + input.Model().WorkingTreeFileCount(2) - input.Press(keys.Files.ViewStashOptions) + input.Views().Files(). + Press(keys.Files.ViewStashOptions) - input.Menu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() + input.ExpectMenu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() - input.Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() + input.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - assert.Model().StashCount(1) - assert.Model().WorkingTreeFileCount(0) + input.Model().StashCount(1) + input.Model().WorkingTreeFileCount(0) }, }) From 53e06b71aecd2ddaf80516627ba223ac2adc5420 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 21:25:11 +1100 Subject: [PATCH 09/20] add tap function --- pkg/integration/components/view.go | 8 ++++ pkg/integration/tests/bisect/basic.go | 42 ++++++++---------- .../tests/bisect/from_other_branch.go | 20 ++++----- .../tests/branch/checkout_by_name.go | 18 ++++---- pkg/integration/tests/branch/delete.go | 24 +++++------ pkg/integration/tests/branch/reset.go | 3 -- .../tests/cherry_pick/cherry_pick.go | 43 +++++++++---------- .../cherry_pick/cherry_pick_conflicts.go | 37 ++++++++-------- pkg/integration/tests/commit/commit.go | 5 ++- pkg/integration/tests/commit/new_branch.go | 24 +++++------ pkg/integration/tests/commit/revert.go | 15 +++---- pkg/integration/tests/commit/staged.go | 34 +++++++-------- .../tests/commit/staged_without_hooks.go | 10 ++--- pkg/integration/tests/commit/unstaged.go | 22 +++++----- pkg/integration/tests/diff/diff.go | 38 ++++++++-------- .../tests/diff/diff_and_apply_patch.go | 40 ++++++++--------- pkg/integration/tests/diff/diff_commits.go | 33 +++++++------- .../tests/interactive_rebase/one.go | 14 +++--- pkg/integration/tests/stash/rename.go | 10 ++--- 19 files changed, 210 insertions(+), 230 deletions(-) diff --git a/pkg/integration/components/view.go b/pkg/integration/components/view.go index e94d0d60c..cda5ff4cb 100644 --- a/pkg/integration/components/view.go +++ b/pkg/integration/components/view.go @@ -194,3 +194,11 @@ func (self *View) NavigateToListItem(matcher *matcher) *View { return self } + +// for when you want to make some assertion unrelated to the current view +// without breaking the method chain +func (self *View) Tap(f func()) *View { + f() + + return self +} diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index 131672654..ac4953095 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -38,34 +38,28 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ input.Views().Commits(). Focus(). SelectedLine(Contains("commit 10")). - NavigateToListItem(Contains("commit 09")) + NavigateToListItem(Contains("commit 09")). + Tap(func() { + markCommitAsBad() - markCommitAsBad() - - input.Views().Information().Content(Contains("bisecting")) - - input.Views().Commits(). - IsFocused(). + input.Views().Information().Content(Contains("bisecting")) + }). SelectedLine(Contains("<-- bad")). - NavigateToListItem(Contains("commit 02")) + NavigateToListItem(Contains("commit 02")). + Tap(markCommitAsGood). + // lazygit will land us in the commit between our good and bad commits. + SelectedLine(Contains("commit 05").Contains("<-- current")). + Tap(markCommitAsBad). + SelectedLine(Contains("commit 04").Contains("<-- current")). + Tap(func() { + markCommitAsGood() - markCommitAsGood() + // commit 5 is the culprit because we marked 4 as good and 5 as bad. + input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() + }). + IsFocused(). + Content(Contains("commit 04")) - // lazygit will land us in the commit between our good and bad commits. - input.Views().Commits().IsFocused(). - SelectedLine(Contains("commit 05").Contains("<-- current")) - - markCommitAsBad() - - input.Views().Commits().IsFocused(). - SelectedLine(Contains("commit 04").Contains("<-- current")) - - markCommitAsGood() - - // commit 5 is the culprit because we marked 4 as good and 5 as bad. - input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() - - input.Views().Commits().IsFocused().Content(Contains("commit 04")) input.Views().Information().Content(DoesNotContain("bisecting")) }, }) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 0112d7da5..20f0fb646 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -36,17 +36,17 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ MatchesRegexp(`<-- good.*commit 05`), ). SelectNextItem(). - Press(keys.Commits.ViewBisectOptions) + Press(keys.Commits.ViewBisectOptions). + Tap(func() { + input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() - input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() + input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() - input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() - - input.Views().Information().Content(DoesNotContain("bisecting")) - - // back in master branch which just had the one commit - input.Views().Commits().Lines( - Contains("only commit on master"), - ) + input.Views().Information().Content(DoesNotContain("bisecting")) + }). + // back in master branch which just had the one commit + Lines( + Contains("only commit on master"), + ) }, }) diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index 59e810dec..2d5e6e098 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -21,22 +21,20 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ input.Views().Branches(). Focus(). Lines( - Contains("master"), + Contains("master").IsSelected(), Contains("@"), ). SelectNextItem(). - Press(keys.Branches.CheckoutBranchByName) + Press(keys.Branches.CheckoutBranchByName). + Tap(func() { + input.ExpectPrompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() - input.ExpectPrompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() - - input.ExpectAlert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() - - input.Views().Branches().IsFocused(). + input.ExpectAlert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() + }). Lines( - MatchesRegexp(`\*.*new-branch`), + MatchesRegexp(`\*.*new-branch`).IsSelected(), Contains("master"), Contains("@"), - ). - SelectedLine(Contains("new-branch")) + ) }, }) diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index eba3a016f..f0921a82e 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -24,20 +24,18 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ MatchesRegexp(`branch-one`), MatchesRegexp(`master`), ). - Press(keys.Universal.Remove) - - input.ExpectAlert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() - - input.Views().Branches(). + Press(keys.Universal.Remove). + Tap(func() { + input.ExpectAlert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() + }). SelectNextItem(). - Press(keys.Universal.Remove) - - input.ExpectConfirmation(). - Title(Equals("Delete Branch")). - Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). - Confirm() - - input.Views().Branches().IsFocused(). + Press(keys.Universal.Remove). + Tap(func() { + input.ExpectConfirmation(). + Title(Equals("Delete Branch")). + Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). + Confirm() + }). Lines( MatchesRegexp(`\*.*branch-two`), MatchesRegexp(`master`).IsSelected(), diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index fc5bbebf0..f96a48b56 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -37,9 +37,6 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ input.ExpectMenu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() - // ensure that we've returned from the menu before continuing - input.Views().Branches().IsFocused() - // assert that we now have the expected commits in the commit panel input.Views().Commits(). Lines( diff --git a/pkg/integration/tests/cherry_pick/cherry_pick.go b/pkg/integration/tests/cherry_pick/cherry_pick.go index 75c060b34..de9e0a645 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -42,11 +42,10 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ Contains("base"), ). // copy commits 'four' and 'three' - Press(keys.Commits.CherryPickCopy) - - input.Views().Information().Content(Contains("1 commit copied")) - - input.Views().SubCommits(). + Press(keys.Commits.CherryPickCopy). + Tap(func() { + input.Views().Information().Content(Contains("1 commit copied")) + }). SelectNextItem(). Press(keys.Commits.CherryPickCopy) @@ -59,29 +58,27 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ Contains("one"), Contains("base"), ). - Press(keys.Commits.PasteCommits) - - input.ExpectAlert(). - Title(Equals("Cherry-Pick")). - Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). - Confirm() - - input.Views().Commits(). - IsFocused(). + Press(keys.Commits.PasteCommits). + Tap(func() { + input.ExpectAlert(). + Title(Equals("Cherry-Pick")). + Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). + Confirm() + }). Lines( Contains("four"), Contains("three"), Contains("two"), Contains("one"), Contains("base"), - ) - - // we need to manually exit out of cherrry pick mode - input.Views().Information().Content(Contains("2 commits copied")) - - input.Views().Commits(). - PressEscape() - - input.Views().Information().Content(DoesNotContain("commits copied")) + ). + Tap(func() { + // we need to manually exit out of cherry pick mode + input.Views().Information().Content(Contains("2 commits copied")) + }). + PressEscape(). + Tap(func() { + input.Views().Information().Content(DoesNotContain("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 9b97be5db..9c02cc8d0 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -31,11 +31,10 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Contains("second-change-branch unrelated change"), Contains("second change"), ). - Press(keys.Commits.CherryPickCopy) - - input.Views().Information().Content(Contains("1 commit copied")) - - input.Views().SubCommits(). + Press(keys.Commits.CherryPickCopy). + Tap(func() { + input.Views().Information().Content(Contains("1 commit copied")) + }). SelectNextItem(). Press(keys.Commits.CherryPickCopy) @@ -80,20 +79,20 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Contains("second change"), Contains("first change"), ). - SelectNextItem() + SelectNextItem(). + Tap(func() { + // because we picked 'Second change' when resolving the conflict, + // we now see this commit as having replaced First Change with Second Change, + // as opposed to replacing 'Original' with 'Second change' + input.Views().Main(). + Content(Contains("-First Change")). + Content(Contains("+Second Change")) - // because we picked 'Second change' when resolving the conflict, - // we now see this commit as having replaced First Change with Second Change, - // as opposed to replacing 'Original' with 'Second change' - input.Views().Main(). - Content(Contains("-First Change")). - Content(Contains("+Second Change")) - - input.Views().Information().Content(Contains("2 commits copied")) - - input.Views().Commits(). - PressEscape() - - input.Views().Information().Content(DoesNotContain("commits copied")) + input.Views().Information().Content(Contains("2 commits copied")) + }). + PressEscape(). + Tap(func() { + input.Views().Information().Content(DoesNotContain("commits copied")) + }) }, }) diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index acd31e4e7..c9bc91fdd 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -28,7 +28,8 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ input.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - input.Model().CommitCount(1) - input.Model().HeadCommitMessage(Equals(commitMessage)) + input.Model(). + CommitCount(1). + HeadCommitMessage(Equals(commitMessage)) }, }) diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index cd194593b..758edb558 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -21,22 +21,22 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ input.Views().Commits(). Focus(). + SelectNextItem(). Lines( Contains("commit 3"), - Contains("commit 2"), + Contains("commit 2").IsSelected(), Contains("commit 1"), ). - SelectNextItem(). - Press(keys.Universal.New) + Press(keys.Universal.New). + Tap(func() { + branchName := "my-branch-name" + input.ExpectPrompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() - branchName := "my-branch-name" - input.ExpectPrompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() - - input.Model().CurrentBranchName(branchName) - - input.Views().Commits().Lines( - Contains("commit 2"), - Contains("commit 1"), - ) + input.Model().CurrentBranchName(branchName) + }). + Lines( + Contains("commit 2"), + Contains("commit 1"), + ) }, }) diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index 24de24e34..23cb5cb8e 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -23,14 +23,13 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ Lines( Contains("first commit"), ). - Press(keys.Commits.RevertCommit) - - input.ExpectConfirmation(). - Title(Equals("Revert commit")). - Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). - Confirm() - - input.Views().Commits().IsFocused(). + Press(keys.Commits.RevertCommit). + Tap(func() { + input.ExpectConfirmation(). + Title(Equals("Revert commit")). + Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). + Confirm() + }). Lines( Contains("Revert \"first commit\"").IsSelected(), Contains("first commit"), diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index 8919ab852..4e5dacd0b 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -24,24 +24,24 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ PressPrimaryAction(). // stage the file PressEnter() - input.Views().StagingSecondary().IsFocused() - // we start with both lines having been staged - input.Views().StagingSecondary().Content(Contains("+myfile content")) - input.Views().StagingSecondary().Content(Contains("+with a second line")) - input.Views().Staging().Content(DoesNotContain("+myfile content")) - input.Views().Staging().Content(DoesNotContain("+with a second line")) - - // unstage the selected line - input.Views().StagingSecondary(). - PressPrimaryAction() - - // the line should have been moved to the main view - input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) - input.Views().StagingSecondary().Content(Contains("+with a second line")) - input.Views().Staging().Content(Contains("+myfile content")) - input.Views().Staging().Content(DoesNotContain("+with a second line")) - input.Views().StagingSecondary(). + IsFocused(). + Tap(func() { + // we start with both lines having been staged + input.Views().StagingSecondary().Content(Contains("+myfile content")) + input.Views().StagingSecondary().Content(Contains("+with a second line")) + input.Views().Staging().Content(DoesNotContain("+myfile content")) + input.Views().Staging().Content(DoesNotContain("+with a second line")) + }). + // unstage the selected line + PressPrimaryAction(). + Tap(func() { + // the line should have been moved to the main view + input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) + input.Views().StagingSecondary().Content(Contains("+with a second line")) + input.Views().Staging().Content(Contains("+myfile content")) + input.Views().Staging().Content(DoesNotContain("+with a second line")) + }). Press(keys.Files.CommitChanges) commitMessage := "my commit message" diff --git a/pkg/integration/tests/commit/staged_without_hooks.go b/pkg/integration/tests/commit/staged_without_hooks.go index d77602d51..9b46f4259 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -36,11 +36,11 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ // unstage the selected line input.Views().StagingSecondary(). IsFocused(). - PressPrimaryAction() - - // the line should have been moved to the main view - input.Views().Staging().Content(Contains("+myfile content").DoesNotContain("+with a second line")) - input.Views().StagingSecondary(). + PressPrimaryAction(). + Tap(func() { + // the line should have been moved to the main view + input.Views().Staging().Content(Contains("+myfile content").DoesNotContain("+with a second line")) + }). Content(DoesNotContain("+myfile content").Contains("+with a second line")). Press(keys.Files.CommitChangesWithoutHook) diff --git a/pkg/integration/tests/commit/unstaged.go b/pkg/integration/tests/commit/unstaged.go index ea08b8462..2d6ba8b8a 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -26,18 +26,16 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ PressEnter() input.Views().Staging(). - IsFocused() - - input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) - - // stage the first line - input.Views().Staging(). - PressPrimaryAction() - - input.Views().Staging().Content(DoesNotContain("+myfile content")) - input.Views().StagingSecondary().Content(Contains("+myfile content")) - - input.Views().Staging(). + IsFocused(). + Tap(func() { + input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) + }). + // stage the first line + PressPrimaryAction(). + Tap(func() { + input.Views().Staging().Content(DoesNotContain("+myfile content")) + input.Views().StagingSecondary().Content(Contains("+myfile content")) + }). Press(keys.Files.CommitChanges) commitMessage := "my commit message" diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index d940b8c20..a30a50589 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -33,35 +33,33 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ input.ExpectMenu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() input.Views().Branches(). - IsFocused() - - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) - - input.Views().Branches(). - SelectNextItem() - - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) - input.Views().Main().Content(Contains("+second line")) - - input.Views().Branches(). + IsFocused(). + Tap(func() { + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) + }). + SelectNextItem(). + Tap(func() { + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) + input.Views().Main().Content(Contains("+second line")) + }). PressEnter() input.Views().SubCommits(). IsFocused(). - SelectedLine(Contains("update")) - - input.Views().Main().Content(Contains("+second line")) - - input.Views().SubCommits(). + SelectedLine(Contains("update")). + Tap(func() { + input.Views().Main().Content(Contains("+second line")) + }). PressEnter() input.Views().CommitFiles(). IsFocused(). - SelectedLine(Contains("file1")) + SelectedLine(Contains("file1")). + Tap(func() { + input.Views().Main().Content(Contains("+second line")) + }). + PressEscape() - input.Views().Main().Content(Contains("+second line")) - - input.Views().CommitFiles().PressEscape() input.Views().SubCommits().PressEscape() input.Views().Branches(). diff --git a/pkg/integration/tests/diff/diff_and_apply_patch.go b/pkg/integration/tests/diff/diff_and_apply_patch.go index 3d78e1c55..65bb27ebd 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -36,38 +36,34 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ input.Views().Branches(). IsFocused(). - SelectNextItem() - - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) - input.Views().Main().Content(Contains("+second line")) - - input.Views().Branches(). + SelectNextItem(). + Tap(func() { + input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) + input.Views().Main().Content(Contains("+second line")) + }). PressEnter() input.Views().SubCommits(). IsFocused(). - SelectedLine(Contains("update")) - - input.Views().Main().Content(Contains("+second line")) - - input.Views().SubCommits(). + SelectedLine(Contains("update")). + Tap(func() { + input.Views().Main().Content(Contains("+second line")) + }). PressEnter() input.Views().CommitFiles(). IsFocused(). - SelectedLine(Contains("file1")) - - input.Views().Main().Content(Contains("+second line")) - - input.Views().CommitFiles(). + SelectedLine(Contains("file1")). + Tap(func() { + input.Views().Main().Content(Contains("+second line")) + }). PressPrimaryAction(). // add the file to the patch - Press(keys.Universal.DiffingMenu) + Press(keys.Universal.DiffingMenu). + Tap(func() { + input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() - input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() - - input.Views().Information().Content(DoesNotContain("building patch")) - - input.Views().CommitFiles(). + input.Views().Information().Content(DoesNotContain("building patch")) + }). Press(keys.Universal.CreatePatchOptionsMenu) // adding the regex '$' here to distinguish the menu item from the 'apply patch in reverse' item diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index 9b05cc582..c8091a17e 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -22,31 +22,28 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ input.Views().Commits(). Focus(). Lines( - Contains("third commit"), + Contains("third commit").IsSelected(), Contains("second commit"), Contains("first commit"), ). - Press(keys.Universal.DiffingMenu) + Press(keys.Universal.DiffingMenu). + Tap(func() { + input.ExpectMenu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() - input.ExpectMenu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() - - input.Views().Information().Content(Contains("showing output for: git diff")) - - input.Views().Commits(). + input.Views().Information().Content(Contains("showing output for: git diff")) + }). SelectNextItem(). SelectNextItem(). - SelectedLine(Contains("first commit")) + SelectedLine(Contains("first commit")). + Tap(func() { + input.Views().Main().Content(Contains("-second line\n-third line")) + }). + Press(keys.Universal.DiffingMenu). + Tap(func() { + input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - input.Views().Main().Content(Contains("-second line\n-third line")) - - input.Views().Commits(). - Press(keys.Universal.DiffingMenu) - - input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - - input.Views().Main().Content(Contains("+second line\n+third line")) - - input.Views().Commits(). + input.Views().Main().Content(Contains("+second line\n+third line")) + }). PressEnter() input.Views().CommitFiles(). diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go index eec707ecc..5e091f7fc 100644 --- a/pkg/integration/tests/interactive_rebase/one.go +++ b/pkg/integration/tests/interactive_rebase/one.go @@ -59,13 +59,13 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ MatchesRegexp("fixup.*commit 03"), MatchesRegexp("YOU ARE HERE.*commit 02"), Contains("commit 01"), + ). + Tap(func() { + input.ContinueRebase() + }). + Lines( + Contains("commit 02"), + Contains("commit 01"), ) - - input.ContinueRebase() - - input.Views().Commits().Lines( - Contains("commit 02"), - Contains("commit 01"), - ) }, }) diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index 48eae4a99..d18ea6f38 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -26,10 +26,10 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ Equals("On master: foo"), ). SelectNextItem(). - Press(keys.Stash.RenameStash) - - input.ExpectPrompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() - - input.Views().Stash().SelectedLine(Equals("On master: foo baz")) + Press(keys.Stash.RenameStash). + Tap(func() { + input.ExpectPrompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() + }). + SelectedLine(Equals("On master: foo baz")) }, }) From 78b495f50a080822121852dfdf27b481dbbd8879 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 21:35:36 +1100 Subject: [PATCH 10/20] rename input to t --- pkg/integration/README.md | 26 ++----- pkg/integration/components/alert_asserter.go | 6 +- .../commit_message_panel_asserter.go | 8 +-- .../components/confirmation_asserter.go | 6 +- pkg/integration/components/menu_asserter.go | 6 +- pkg/integration/components/prompt_asserter.go | 20 +++--- pkg/integration/components/test.go | 10 +-- .../components/{input.go => test_driver.go} | 68 +++++++++---------- pkg/integration/components/test_test.go | 20 +++--- pkg/integration/components/view.go | 51 ++++++-------- pkg/integration/components/views.go | 18 ++--- pkg/integration/tests/bisect/basic.go | 20 +++--- .../tests/bisect/from_other_branch.go | 14 ++-- .../tests/branch/checkout_by_name.go | 8 +-- pkg/integration/tests/branch/delete.go | 8 +-- pkg/integration/tests/branch/rebase.go | 22 +++--- .../tests/branch/rebase_and_drop.go | 26 +++---- pkg/integration/tests/branch/reset.go | 10 +-- pkg/integration/tests/branch/suggestions.go | 8 +-- .../tests/cherry_pick/cherry_pick.go | 18 ++--- .../cherry_pick/cherry_pick_conflicts.go | 32 ++++----- pkg/integration/tests/commit/commit.go | 10 +-- .../tests/commit/commit_multiline.go | 16 ++--- pkg/integration/tests/commit/new_branch.go | 10 +-- pkg/integration/tests/commit/revert.go | 12 ++-- pkg/integration/tests/commit/staged.go | 32 ++++----- .../tests/commit/staged_without_hooks.go | 22 +++--- pkg/integration/tests/commit/unstaged.go | 24 +++---- .../tests/config/remote_named_star.go | 4 +- .../tests/custom_commands/basic.go | 6 +- .../tests/custom_commands/form_prompts.go | 18 ++--- .../custom_commands/menu_from_command.go | 16 ++--- .../menu_from_commands_output.go | 14 ++-- .../tests/custom_commands/multiple_prompts.go | 18 ++--- pkg/integration/tests/diff/diff.go | 32 ++++----- .../tests/diff/diff_and_apply_patch.go | 32 ++++----- pkg/integration/tests/diff/diff_commits.go | 18 ++--- .../tests/file/dir_with_untracked_file.go | 6 +- pkg/integration/tests/file/discard_changes.go | 12 ++-- .../tests/interactive_rebase/amend_merge.go | 16 ++--- .../tests/interactive_rebase/one.go | 6 +- pkg/integration/tests/misc/confirm_on_quit.go | 8 +-- pkg/integration/tests/stash/rename.go | 6 +- pkg/integration/tests/stash/stash.go | 16 ++--- .../stash/stash_including_untracked_files.go | 16 ++--- 45 files changed, 376 insertions(+), 399 deletions(-) rename pkg/integration/components/{input.go => test_driver.go} (77%) diff --git a/pkg/integration/README.md b/pkg/integration/README.md index fe4f43ac1..2da3b5f81 100644 --- a/pkg/integration/README.md +++ b/pkg/integration/README.md @@ -24,16 +24,15 @@ In the setup step, we prepare a repo with shell commands, for example, creating ### Run step -The run step has four arguments passed in: +The run step has three arguments passed in: 1. `shell` -2. `input` -3. `assert` +2. `t` (the test driver) 4. `keys` `shell` we've already seen in the setup step. The reason it's passed into the run step is that we may want to emulate background events. For example, the user modifying a file outside of lazygit. -`input` is for driving the gui by pressing certain keys, selecting list items, etc. +`t` is for driving the gui by pressing certain keys, selecting list items, etc. `assert` is for asserting on the state of the lazygit session. When you call a method on `assert`, the assert struct will wait for the assertion to hold true and then continue (failing the test after a timeout). For this reason, assertions have two purposes: one is to ensure the test fails as soon as something unexpected happens, but another is to allow lazygit to process a keypress before you follow up with more keypresses. If you input a bunch of keypresses too quickly lazygit might get confused. @@ -43,32 +42,21 @@ 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. -#### Assert after input - -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) -input.InCommitMessagePanel() -``` - -Note that there are some `input` methods that have assertions baked in, such as the `SwitchToView` methods. - #### 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 `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. +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. 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") +t.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")) +t.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?")) +t.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure?")) ``` ## Running tests diff --git a/pkg/integration/components/alert_asserter.go b/pkg/integration/components/alert_asserter.go index abc2f1171..2010af3b8 100644 --- a/pkg/integration/components/alert_asserter.go +++ b/pkg/integration/components/alert_asserter.go @@ -1,13 +1,13 @@ package components type AlertAsserter struct { - input *Input + t *TestDriver hasCheckedTitle bool hasCheckedContent bool } func (self *AlertAsserter) getViewAsserter() *View { - return self.input.Views().Confirmation() + return self.t.Views().Confirmation() } // asserts that the alert view has the expected title @@ -42,6 +42,6 @@ func (self *AlertAsserter) Cancel() { func (self *AlertAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedContent || !self.hasCheckedTitle { - self.input.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") + self.t.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") } } diff --git a/pkg/integration/components/commit_message_panel_asserter.go b/pkg/integration/components/commit_message_panel_asserter.go index 9aacacf89..aad82720f 100644 --- a/pkg/integration/components/commit_message_panel_asserter.go +++ b/pkg/integration/components/commit_message_panel_asserter.go @@ -1,11 +1,11 @@ package components type CommitMessagePanelAsserter struct { - input *Input + t *TestDriver } func (self *CommitMessagePanelAsserter) getViewAsserter() *View { - return self.input.Views().CommitMessage() + return self.t.Views().CommitMessage() } // asserts on the text initially present in the prompt @@ -16,13 +16,13 @@ func (self *CommitMessagePanelAsserter) InitialText(expected *matcher) *CommitMe } func (self *CommitMessagePanelAsserter) Type(value string) *CommitMessagePanelAsserter { - self.input.typeContent(value) + self.t.typeContent(value) return self } func (self *CommitMessagePanelAsserter) AddNewline() *CommitMessagePanelAsserter { - self.input.press(self.input.keys.Universal.AppendNewline) + self.t.press(self.t.keys.Universal.AppendNewline) return self } diff --git a/pkg/integration/components/confirmation_asserter.go b/pkg/integration/components/confirmation_asserter.go index 2d3d87ba0..b226f0885 100644 --- a/pkg/integration/components/confirmation_asserter.go +++ b/pkg/integration/components/confirmation_asserter.go @@ -1,13 +1,13 @@ package components type ConfirmationAsserter struct { - input *Input + t *TestDriver hasCheckedTitle bool hasCheckedContent bool } func (self *ConfirmationAsserter) getViewAsserter() *View { - return self.input.Views().Confirmation() + return self.t.Views().Confirmation() } // asserts that the confirmation view has the expected title @@ -42,6 +42,6 @@ func (self *ConfirmationAsserter) Cancel() { func (self *ConfirmationAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedContent || !self.hasCheckedTitle { - self.input.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") + self.t.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") } } diff --git a/pkg/integration/components/menu_asserter.go b/pkg/integration/components/menu_asserter.go index 4f1fd035a..42e31a610 100644 --- a/pkg/integration/components/menu_asserter.go +++ b/pkg/integration/components/menu_asserter.go @@ -1,12 +1,12 @@ package components type MenuAsserter struct { - input *Input + t *TestDriver hasCheckedTitle bool } func (self *MenuAsserter) getViewAsserter() *View { - return self.input.Views().Menu() + return self.t.Views().Menu() } // asserts that the popup has the expected title @@ -38,6 +38,6 @@ func (self *MenuAsserter) Select(option *matcher) *MenuAsserter { func (self *MenuAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedTitle { - self.input.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().") + self.t.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().") } } diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go index 343d9d54b..9fea5bdf2 100644 --- a/pkg/integration/components/prompt_asserter.go +++ b/pkg/integration/components/prompt_asserter.go @@ -1,12 +1,12 @@ package components type PromptAsserter struct { - input *Input + t *TestDriver hasCheckedTitle bool } func (self *PromptAsserter) getViewAsserter() *View { - return self.input.Views().Confirmation() + return self.t.Views().Confirmation() } // asserts that the popup has the expected title @@ -26,7 +26,7 @@ func (self *PromptAsserter) InitialText(expected *matcher) *PromptAsserter { } func (self *PromptAsserter) Type(value string) *PromptAsserter { - self.input.typeContent(value) + self.t.typeContent(value) return self } @@ -49,25 +49,25 @@ func (self *PromptAsserter) Cancel() { func (self *PromptAsserter) checkNecessaryChecksCompleted() { if !self.hasCheckedTitle { - self.input.Fail("You must check the title of a prompt popup by calling Title() before calling Confirm()/Cancel().") + self.t.Fail("You must check the title of a prompt popup by calling Title() before calling Confirm()/Cancel().") } } func (self *PromptAsserter) SuggestionLines(matchers ...*matcher) *PromptAsserter { - self.input.Views().Suggestions().Lines(matchers...) + self.t.Views().Suggestions().Lines(matchers...) return self } func (self *PromptAsserter) SuggestionTopLines(matchers ...*matcher) *PromptAsserter { - self.input.Views().Suggestions().TopLines(matchers...) + self.t.Views().Suggestions().TopLines(matchers...) return self } func (self *PromptAsserter) SelectFirstSuggestion() *PromptAsserter { - self.input.press(self.input.keys.Universal.TogglePanel) - self.input.Views().Suggestions(). + self.t.press(self.t.keys.Universal.TogglePanel) + self.t.Views().Suggestions(). IsFocused(). SelectedLineIdx(0) @@ -75,8 +75,8 @@ func (self *PromptAsserter) SelectFirstSuggestion() *PromptAsserter { } func (self *PromptAsserter) SelectSuggestion(matcher *matcher) *PromptAsserter { - self.input.press(self.input.keys.Universal.TogglePanel) - self.input.Views().Suggestions(). + self.t.press(self.t.keys.Universal.TogglePanel) + self.t.Views().Suggestions(). IsFocused(). NavigateToListItem(matcher) diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go index 705323ecb..927dfb36c 100644 --- a/pkg/integration/components/test.go +++ b/pkg/integration/components/test.go @@ -25,7 +25,7 @@ type IntegrationTest struct { setupConfig func(config *config.AppConfig) run func( shell *Shell, - input *Input, + testController *TestDriver, keys config.KeybindingConfig, ) } @@ -40,7 +40,7 @@ type NewIntegrationTestArgs struct { // takes a config and mutates. The mutated context will end up being passed to the gui SetupConfig func(config *config.AppConfig) // runs the test - Run func(shell *Shell, input *Input, keys config.KeybindingConfig) + Run func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) // additional args passed to lazygit ExtraCmdArgs string // for when a test is flakey @@ -94,13 +94,13 @@ func (self *IntegrationTest) SetupRepo(shell *Shell) { func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) { shell := NewShell("/tmp/lazygit-test") keys := gui.Keys() - input := NewInput(gui, keys, KeyPressDelay()) + testController := NewTestController(gui, keys, KeyPressDelay()) - self.run(shell, input, keys) + self.run(shell, testController, keys) if KeyPressDelay() > 0 { // the dev would want to see the final state if they're running in slow mode - input.Wait(2000) + testController.Wait(2000) } } diff --git a/pkg/integration/components/input.go b/pkg/integration/components/test_driver.go similarity index 77% rename from pkg/integration/components/input.go rename to pkg/integration/components/test_driver.go index d5db33518..7b3fb0889 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/test_driver.go @@ -11,15 +11,15 @@ import ( "github.com/samber/lo" ) -type Input struct { +type TestDriver struct { gui integrationTypes.GuiDriver keys config.KeybindingConfig pushKeyDelay int *assertionHelper } -func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, pushKeyDelay int) *Input { - return &Input{ +func NewTestController(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, pushKeyDelay int) *TestDriver { + return &TestDriver{ gui: gui, keys: keys, pushKeyDelay: pushKeyDelay, @@ -29,19 +29,19 @@ func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, push // 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) press(keyStr string) { +func (self *TestDriver) press(keyStr string) { self.Wait(self.pushKeyDelay) self.gui.PressKey(keyStr) } -func (self *Input) typeContent(content string) { +func (self *TestDriver) typeContent(content string) { for _, char := range content { self.press(string(char)) } } -func (self *Input) ContinueMerge() { +func (self *TestDriver) ContinueMerge() { self.Views().current().Press(self.keys.Universal.CreateRebaseOptionsMenu) self.ExpectMenu(). @@ -50,20 +50,20 @@ func (self *Input) ContinueMerge() { Confirm() } -func (self *Input) ContinueRebase() { +func (self *TestDriver) ContinueRebase() { self.ContinueMerge() } // for when you want to allow lazygit to process something before continuing -func (self *Input) Wait(milliseconds int) { +func (self *TestDriver) Wait(milliseconds int) { time.Sleep(time.Duration(milliseconds) * time.Millisecond) } -func (self *Input) LogUI(message string) { +func (self *TestDriver) LogUI(message string) { self.gui.LogUI(message) } -func (self *Input) Log(message string) { +func (self *TestDriver) Log(message string) { self.gui.LogUI(message) } @@ -78,7 +78,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) navigateToListItem(matcher *matcher) { +func (self *TestDriver) navigateToListItem(matcher *matcher) { self.inListContext() currentContext := self.gui.CurrentContext().(types.IListContext) @@ -128,7 +128,7 @@ func (self *Input) navigateToListItem(matcher *matcher) { } } -func (self *Input) inListContext() { +func (self *TestDriver) inListContext() { self.assertWithRetries(func() (bool, string) { currentContext := self.gui.CurrentContext() _, ok := currentContext.(types.IListContext) @@ -136,39 +136,39 @@ func (self *Input) inListContext() { }) } -func (self *Input) ExpectConfirmation() *ConfirmationAsserter { +func (self *TestDriver) ExpectConfirmation() *ConfirmationAsserter { self.inConfirm() - return &ConfirmationAsserter{input: self} + return &ConfirmationAsserter{t: self} } -func (self *Input) inConfirm() { +func (self *TestDriver) inConfirm() { self.assertWithRetries(func() (bool, string) { currentView := self.gui.CurrentContext().GetView() return currentView.Name() == "confirmation" && !currentView.Editable, "Expected confirmation popup to be focused" }) } -func (self *Input) ExpectPrompt() *PromptAsserter { +func (self *TestDriver) ExpectPrompt() *PromptAsserter { self.inPrompt() - return &PromptAsserter{input: self} + return &PromptAsserter{t: self} } -func (self *Input) inPrompt() { +func (self *TestDriver) inPrompt() { self.assertWithRetries(func() (bool, string) { currentView := self.gui.CurrentContext().GetView() return currentView.Name() == "confirmation" && currentView.Editable, "Expected prompt popup to be focused" }) } -func (self *Input) ExpectAlert() *AlertAsserter { +func (self *TestDriver) ExpectAlert() *AlertAsserter { self.inAlert() - return &AlertAsserter{input: self} + return &AlertAsserter{t: self} } -func (self *Input) inAlert() { +func (self *TestDriver) inAlert() { // basically the same thing as a confirmation popup with the current implementation self.assertWithRetries(func() (bool, string) { currentView := self.gui.CurrentContext().GetView() @@ -176,32 +176,32 @@ func (self *Input) inAlert() { }) } -func (self *Input) ExpectMenu() *MenuAsserter { +func (self *TestDriver) ExpectMenu() *MenuAsserter { self.inMenu() - return &MenuAsserter{input: self} + return &MenuAsserter{t: self} } -func (self *Input) inMenu() { +func (self *TestDriver) inMenu() { self.assertWithRetries(func() (bool, string) { return self.gui.CurrentContext().GetView().Name() == "menu", "Expected popup menu to be focused" }) } -func (self *Input) ExpectCommitMessagePanel() *CommitMessagePanelAsserter { +func (self *TestDriver) ExpectCommitMessagePanel() *CommitMessagePanelAsserter { self.inCommitMessagePanel() - return &CommitMessagePanelAsserter{input: self} + return &CommitMessagePanelAsserter{t: self} } -func (self *Input) inCommitMessagePanel() { +func (self *TestDriver) inCommitMessagePanel() { self.assertWithRetries(func() (bool, string) { currentView := self.gui.CurrentContext().GetView() return currentView.Name() == "commitMessage", "Expected commit message panel to be focused" }) } -func (self *Input) currentWindowName(expectedWindowName string) { +func (self *TestDriver) currentWindowName(expectedWindowName string) { self.assertWithRetries(func() (bool, string) { actual := self.gui.CurrentContext().GetView().Name() return actual == expectedWindowName, fmt.Sprintf("Expected current window name to be '%s', but got '%s'", expectedWindowName, actual) @@ -209,27 +209,27 @@ func (self *Input) currentWindowName(expectedWindowName string) { } // for making assertions on lazygit views -func (self *Input) Views() *Views { - return &Views{input: self} +func (self *TestDriver) Views() *Views { + return &Views{t: self} } // for making assertions on the lazygit model -func (self *Input) Model() *Model { +func (self *TestDriver) Model() *Model { return &Model{assertionHelper: self.assertionHelper, gui: self.gui} } // for making assertions on the file system -func (self *Input) FileSystem() *FileSystem { +func (self *TestDriver) FileSystem() *FileSystem { return &FileSystem{assertionHelper: self.assertionHelper} } // for when you just want to fail the test yourself. // This runs callbacks to ensure we render the error after closing the gui. -func (self *Input) Fail(message string) { +func (self *TestDriver) Fail(message string) { self.assertionHelper.fail(message) } -func (self *Input) NotInPopup() { +func (self *TestDriver) NotInPopup() { self.assertWithRetries(func() (bool, string) { viewName := self.gui.CurrentContext().GetView().Name() return !lo.Contains([]string{"menu", "confirmation", "commitMessage"}, viewName), fmt.Sprintf("Unexpected popup view present: %s view", viewName) diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index 1356fbf3b..79d2b3955 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -63,10 +63,10 @@ func (self *fakeGuiDriver) View(viewName string) *gocui.View { func TestAssertionFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.press("a") - input.press("b") - input.Model().CommitCount(2) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.press("a") + t.press("b") + t.Model().CommitCount(2) }, }) driver := &fakeGuiDriver{} @@ -78,8 +78,8 @@ func TestAssertionFailure(t *testing.T) { func TestManualFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Fail("blah") + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Fail("blah") }, }) driver := &fakeGuiDriver{} @@ -90,10 +90,10 @@ func TestManualFailure(t *testing.T) { func TestSuccess(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.press("a") - input.press("b") - input.Model().CommitCount(0) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.press("a") + t.press("b") + t.Model().CommitCount(0) }, }) driver := &fakeGuiDriver{} diff --git a/pkg/integration/components/view.go b/pkg/integration/components/view.go index cda5ff4cb..479c419cc 100644 --- a/pkg/integration/components/view.go +++ b/pkg/integration/components/view.go @@ -10,23 +10,12 @@ type View struct { // context is prepended to any error messages e.g. 'context: "current view"' context string getView func() *gocui.View - input *Input -} - -// asserts that the view has the expected name. This is typically used in tandem with the CurrentView method i.e.; -// input.CurrentView().Name("commits") to assert that the current view is the commits view. -func (self *View) Name(expected string) *View { - self.input.assertWithRetries(func() (bool, string) { - actual := self.getView().Name() - return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual) - }) - - return self + t *TestDriver } // asserts that the view has the expected title func (self *View) Title(expected *matcher) *View { - self.input.assertWithRetries(func() (bool, string) { + self.t.assertWithRetries(func() (bool, string) { actual := self.getView().Title return expected.context(fmt.Sprintf("%s title", self.context)).test(actual) }) @@ -39,7 +28,7 @@ func (self *View) Title(expected *matcher) *View { // This method is convenient when you have a list of commits but you only want to // assert on the first couple of commits. func (self *View) TopLines(matchers ...*matcher) *View { - self.input.assertWithRetries(func() (bool, string) { + self.t.assertWithRetries(func() (bool, string) { lines := self.getView().BufferLines() return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines)) }) @@ -50,7 +39,7 @@ func (self *View) TopLines(matchers ...*matcher) *View { // 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. func (self *View) Lines(matchers ...*matcher) *View { - self.input.assertWithRetries(func() (bool, string) { + self.t.assertWithRetries(func() (bool, string) { lines := self.getView().BufferLines() return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines)) }) @@ -64,14 +53,14 @@ func (self *View) assertLines(matchers ...*matcher) *View { for i, matcher := range matchers { checkIsSelected, matcher := matcher.checkIsSelected() - self.input.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()), + self.t.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()), func() string { return view.BufferLines()[i] }, ) if checkIsSelected { - self.input.assertWithRetries(func() (bool, string) { + self.t.assertWithRetries(func() (bool, string) { lineIdx := view.SelectedLineIdx() return lineIdx == i, fmt.Sprintf("Unexpected selected line index in view '%s'. Expected %d, got %d", view.Name(), i, lineIdx) }) @@ -83,7 +72,7 @@ func (self *View) assertLines(matchers ...*matcher) *View { // asserts on the content of the view i.e. the stuff within the view's frame. func (self *View) Content(matcher *matcher) *View { - self.input.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), + self.t.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), func() string { return self.getView().Buffer() }, @@ -94,7 +83,7 @@ func (self *View) Content(matcher *matcher) *View { // asserts on the selected line of the view func (self *View) SelectedLine(matcher *matcher) *View { - self.input.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context), + self.t.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context), func() string { return self.getView().SelectedLine() }, @@ -105,7 +94,7 @@ func (self *View) SelectedLine(matcher *matcher) *View { // asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view. func (self *View) SelectedLineIdx(expected int) *View { - self.input.assertWithRetries(func() (bool, string) { + self.t.assertWithRetries(func() (bool, string) { actual := self.getView().SelectedLineIdx() return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual) }) @@ -132,10 +121,10 @@ func (self *View) Focus() *View { index, ok := windowIndexMap[viewName] if !ok { - self.input.fail(fmt.Sprintf("Cannot focus view %s: Focus() method not implemented", viewName)) + self.t.fail(fmt.Sprintf("Cannot focus view %s: Focus() method not implemented", viewName)) } - self.input.press(self.input.keys.Universal.JumpToBlock[index]) + self.t.press(self.t.keys.Universal.JumpToBlock[index]) // assert that we land in the expected view self.IsFocused() @@ -145,9 +134,9 @@ func (self *View) Focus() *View { // asserts that the view is focused func (self *View) IsFocused() *View { - self.input.assertWithRetries(func() (bool, string) { + self.t.assertWithRetries(func() (bool, string) { expected := self.getView().Name() - actual := self.input.gui.CurrentContext().GetView().Name() + actual := self.t.gui.CurrentContext().GetView().Name() return actual == expected, fmt.Sprintf("%s: Unexpected view focused. Expected %s, got %s", self.context, expected, actual) }) @@ -157,40 +146,40 @@ func (self *View) IsFocused() *View { func (self *View) Press(keyStr string) *View { self.IsFocused() - self.input.press(keyStr) + self.t.press(keyStr) return self } // i.e. pressing down arrow func (self *View) SelectNextItem() *View { - return self.Press(self.input.keys.Universal.NextItem) + return self.Press(self.t.keys.Universal.NextItem) } // i.e. pressing up arrow func (self *View) SelectPreviousItem() *View { - return self.Press(self.input.keys.Universal.PrevItem) + return self.Press(self.t.keys.Universal.PrevItem) } // i.e. pressing space func (self *View) PressPrimaryAction() *View { - return self.Press(self.input.keys.Universal.Select) + return self.Press(self.t.keys.Universal.Select) } // i.e. pressing space func (self *View) PressEnter() *View { - return self.Press(self.input.keys.Universal.Confirm) + return self.Press(self.t.keys.Universal.Confirm) } // i.e. pressing escape func (self *View) PressEscape() *View { - return self.Press(self.input.keys.Universal.Return) + return self.Press(self.t.keys.Universal.Return) } func (self *View) NavigateToListItem(matcher *matcher) *View { self.IsFocused() - self.input.navigateToListItem(matcher) + self.t.navigateToListItem(matcher) return self } diff --git a/pkg/integration/components/views.go b/pkg/integration/components/views.go index 9efe7cdcf..4a95e5e0f 100644 --- a/pkg/integration/components/views.go +++ b/pkg/integration/components/views.go @@ -7,7 +7,7 @@ import ( ) type Views struct { - input *Input + t *TestDriver } // not exporting this because I want the test to always be explicit about what @@ -15,32 +15,32 @@ type Views struct { func (self *Views) current() *View { return &View{ context: "current view", - getView: func() *gocui.View { return self.input.gui.CurrentContext().GetView() }, - input: self.input, + getView: func() *gocui.View { return self.t.gui.CurrentContext().GetView() }, + t: self.t, } } func (self *Views) Main() *View { return &View{ context: "main view", - getView: func() *gocui.View { return self.input.gui.MainView() }, - input: self.input, + getView: func() *gocui.View { return self.t.gui.MainView() }, + t: self.t, } } func (self *Views) Secondary() *View { return &View{ context: "secondary view", - getView: func() *gocui.View { return self.input.gui.SecondaryView() }, - input: self.input, + getView: func() *gocui.View { return self.t.gui.SecondaryView() }, + t: self.t, } } func (self *Views) ByName(viewName string) *View { return &View{ context: fmt.Sprintf("%s view", viewName), - getView: func() *gocui.View { return self.input.gui.View(viewName) }, - input: self.input, + getView: func() *gocui.View { return self.t.gui.View(viewName) }, + t: self.t, } } diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index ac4953095..cbb37aac7 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -16,33 +16,33 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ SetupConfig: func(cfg *config.AppConfig) {}, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { markCommitAsBad := func() { - input.Views().Commits(). + t.Views().Commits(). Press(keys.Commits.ViewBisectOptions) - input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as bad`)).Confirm() + t.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as bad`)).Confirm() } markCommitAsGood := func() { - input.Views().Commits(). + t.Views().Commits(). Press(keys.Commits.ViewBisectOptions) - input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() + t.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() } - input.Model().AtLeastOneCommit() + t.Model().AtLeastOneCommit() - input.Views().Commits(). + t.Views().Commits(). Focus(). SelectedLine(Contains("commit 10")). NavigateToListItem(Contains("commit 09")). Tap(func() { markCommitAsBad() - input.Views().Information().Content(Contains("bisecting")) + t.Views().Information().Content(Contains("bisecting")) }). SelectedLine(Contains("<-- bad")). NavigateToListItem(Contains("commit 02")). @@ -55,11 +55,11 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ markCommitAsGood() // commit 5 is the culprit because we marked 4 as good and 5 as bad. - input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() + t.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() }). IsFocused(). Content(Contains("commit 04")) - input.Views().Information().Content(DoesNotContain("bisecting")) + t.Views().Information().Content(DoesNotContain("bisecting")) }, }) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 20f0fb646..8759e28f3 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -20,14 +20,14 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ SetupConfig: func(cfg *config.AppConfig) {}, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { - input.Views().Information().Content(Contains("bisecting")) + t.Views().Information().Content(Contains("bisecting")) - input.Model().AtLeastOneCommit() + t.Model().AtLeastOneCommit() - input.Views().Commits(). + t.Views().Commits(). Focus(). TopLines( MatchesRegexp(`<-- bad.*commit 08`), @@ -38,11 +38,11 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Commits.ViewBisectOptions). Tap(func() { - input.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() + t.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() - input.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() + t.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() - input.Views().Information().Content(DoesNotContain("bisecting")) + t.Views().Information().Content(DoesNotContain("bisecting")) }). // back in master branch which just had the one commit Lines( diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index 2d5e6e098..7a8733d26 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -17,8 +17,8 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ Checkout("master"). EmptyCommit("blah") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). Lines( Contains("master").IsSelected(), @@ -27,9 +27,9 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Branches.CheckoutBranchByName). Tap(func() { - input.ExpectPrompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() + t.ExpectPrompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() - input.ExpectAlert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() + t.ExpectAlert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() }). Lines( MatchesRegexp(`\*.*new-branch`).IsSelected(), diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index f0921a82e..6410576e8 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -16,8 +16,8 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ NewBranch("branch-one"). NewBranch("branch-two") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). Lines( MatchesRegexp(`\*.*branch-two`).IsSelected(), @@ -26,12 +26,12 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.Remove). Tap(func() { - input.ExpectAlert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() + t.ExpectAlert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() }). SelectNextItem(). Press(keys.Universal.Remove). Tap(func() { - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Delete Branch")). Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). Confirm() diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index 541493458..b90810b82 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -14,13 +14,13 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Commits().TopLines( + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits().TopLines( Contains("first change"), Contains("original"), ) - input.Views().Branches(). + t.Views().Branches(). Focus(). Lines( Contains("first-change-branch"), @@ -30,35 +30,35 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Branches.RebaseBranch) - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() - input.Views().Files(). + t.Views().Files(). IsFocused(). SelectedLine(Contains("file")). PressEnter() - input.Views().MergeConflicts(). + t.Views().MergeConflicts(). IsFocused(). PressPrimaryAction() - input.Views().Information().Content(Contains("rebasing")) + t.Views().Information().Content(Contains("rebasing")) - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - input.Views().Information().Content(DoesNotContain("rebasing")) + t.Views().Information().Content(DoesNotContain("rebasing")) - input.Views().Commits().TopLines( + t.Views().Commits().TopLines( Contains("second-change-branch unrelated change"), Contains("second change"), Contains("original"), diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 53a718618..610bb1c19 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -17,8 +17,8 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ shell.EmptyCommit("to remove") shell.EmptyCommit("to keep") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). Lines( Contains("first-change-branch"), @@ -26,7 +26,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ Contains("original-branch"), ) - input.Views().Commits(). + t.Views().Commits(). TopLines( Contains("to keep").IsSelected(), Contains("to remove"), @@ -36,22 +36,22 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Branches.RebaseBranch) - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - input.Views().Information().Content(Contains("rebasing")) + t.Views().Information().Content(Contains("rebasing")) - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() - input.Views().Files().IsFocused(). + t.Views().Files().IsFocused(). SelectedLine(MatchesRegexp("UU.*file")) - input.Views().Commits(). + t.Views().Commits(). Focus(). TopLines( MatchesRegexp(`pick.*to keep`).IsSelected(), @@ -70,22 +70,22 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ MatchesRegexp("original"), ) - input.Views().Files(). + t.Views().Files(). Focus(). PressEnter() - input.Views().MergeConflicts(). + t.Views().MergeConflicts(). IsFocused(). PressPrimaryAction() - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - input.Views().Information().Content(DoesNotContain("rebasing")) + t.Views().Information().Content(DoesNotContain("rebasing")) - input.Views().Commits().TopLines( + t.Views().Commits().TopLines( Contains("to keep"), Contains("second-change-branch unrelated change").IsSelected(), Contains("second change"), diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index f96a48b56..bfd1b950f 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -20,13 +20,13 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("current-branch") shell.EmptyCommit("current-branch commit") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Commits().Lines( + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits().Lines( Contains("current-branch commit"), Contains("root commit"), ) - input.Views().Branches(). + t.Views().Branches(). Focus(). Lines( Contains("current-branch"), @@ -35,10 +35,10 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Commits.ViewResetOptions) - input.ExpectMenu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() + t.ExpectMenu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() // assert that we now have the expected commits in the commit panel - input.Views().Commits(). + t.Views().Commits(). Lines( Contains("other-branch commit"), Contains("root commit"), diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index 9999947d9..438bbf9be 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -20,20 +20,20 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ NewBranch("other-new-branch-2"). NewBranch("other-new-branch-3") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). Press(keys.Branches.CheckoutBranchByName) // we expect the first suggestion to be the branch we want because it most // closely matches what we typed in - input.ExpectPrompt(). + t.ExpectPrompt(). Title(Equals("Branch name:")). Type("branch-to"). SuggestionTopLines(Contains("branch-to-checkout")). SelectFirstSuggestion(). Confirm() - input.Model().CurrentBranchName("branch-to-checkout") + t.Model().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 de9e0a645..5fa2d47ac 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -23,8 +23,8 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("four"). Checkout("first-branch") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). Lines( Contains("first-branch"), @@ -34,7 +34,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). PressEnter() - input.Views().SubCommits(). + t.Views().SubCommits(). IsFocused(). Lines( Contains("four").IsSelected(), @@ -44,14 +44,14 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ // copy commits 'four' and 'three' Press(keys.Commits.CherryPickCopy). Tap(func() { - input.Views().Information().Content(Contains("1 commit copied")) + t.Views().Information().Content(Contains("1 commit copied")) }). SelectNextItem(). Press(keys.Commits.CherryPickCopy) - input.Views().Information().Content(Contains("2 commits copied")) + t.Views().Information().Content(Contains("2 commits copied")) - input.Views().Commits(). + t.Views().Commits(). Focus(). Lines( Contains("two").IsSelected(), @@ -60,7 +60,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Commits.PasteCommits). Tap(func() { - input.ExpectAlert(). + t.ExpectAlert(). Title(Equals("Cherry-Pick")). Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). Confirm() @@ -74,11 +74,11 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ ). Tap(func() { // we need to manually exit out of cherry pick mode - input.Views().Information().Content(Contains("2 commits copied")) + t.Views().Information().Content(Contains("2 commits copied")) }). PressEscape(). Tap(func() { - input.Views().Information().Content(DoesNotContain("commits copied")) + t.Views().Information().Content(DoesNotContain("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 9c02cc8d0..5de63baa6 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -14,8 +14,8 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). Lines( Contains("first-change-branch"), @@ -25,7 +25,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). PressEnter() - input.Views().SubCommits(). + t.Views().SubCommits(). IsFocused(). TopLines( Contains("second-change-branch unrelated change"), @@ -33,46 +33,46 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Commits.CherryPickCopy). Tap(func() { - input.Views().Information().Content(Contains("1 commit copied")) + t.Views().Information().Content(Contains("1 commit copied")) }). SelectNextItem(). Press(keys.Commits.CherryPickCopy) - input.Views().Information().Content(Contains("2 commits copied")) + t.Views().Information().Content(Contains("2 commits copied")) - input.Views().Commits(). + t.Views().Commits(). Focus(). TopLines( Contains("first change"), ). Press(keys.Commits.PasteCommits) - input.ExpectAlert().Title(Equals("Cherry-Pick")).Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).Confirm() + t.ExpectAlert().Title(Equals("Cherry-Pick")).Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).Confirm() - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() - input.Views().Files(). + t.Views().Files(). IsFocused(). SelectedLine(Contains("file")). PressEnter() - input.Views().MergeConflicts(). + t.Views().MergeConflicts(). IsFocused(). // picking 'Second change' SelectNextItem(). PressPrimaryAction() - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - input.Model().WorkingTreeFileCount(0) + t.Model().WorkingTreeFileCount(0) - input.Views().Commits(). + t.Views().Commits(). Focus(). TopLines( Contains("second-change-branch unrelated change"), @@ -84,15 +84,15 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ // because we picked 'Second change' when resolving the conflict, // we now see this commit as having replaced First Change with Second Change, // as opposed to replacing 'Original' with 'Second change' - input.Views().Main(). + t.Views().Main(). Content(Contains("-First Change")). Content(Contains("+Second Change")) - input.Views().Information().Content(Contains("2 commits copied")) + t.Views().Information().Content(Contains("2 commits copied")) }). PressEscape(). Tap(func() { - input.Views().Information().Content(DoesNotContain("commits copied")) + t.Views().Information().Content(DoesNotContain("commits copied")) }) }, }) diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index c9bc91fdd..951529cea 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -14,10 +14,10 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("myfile", "myfile content") shell.CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(0) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). PressPrimaryAction(). // stage file SelectNextItem(). @@ -26,9 +26,9 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ commitMessage := "my commit message" - input.ExpectCommitMessagePanel().Type(commitMessage).Confirm() + t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - input.Model(). + t.Model(). CommitCount(1). HeadCommitMessage(Equals(commitMessage)) }, diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index 4f80adbe1..823412f68 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -13,20 +13,20 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shell.CreateFile("myfile", "myfile content") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(0) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). PressPrimaryAction(). Press(keys.Files.CommitChanges) - input.ExpectCommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() + t.ExpectCommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() - input.Model().CommitCount(1) - input.Model().HeadCommitMessage(Equals("first line")) + t.Model().CommitCount(1) + t.Model().HeadCommitMessage(Equals("first line")) - input.Views().Commits().Focus() - input.Views().Main().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) + t.Views().Commits().Focus() + t.Views().Main().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) }, }) diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index 758edb558..f2deecdc9 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -16,10 +16,10 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("commit 2"). EmptyCommit("commit 3") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(3) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(3) - input.Views().Commits(). + t.Views().Commits(). Focus(). SelectNextItem(). Lines( @@ -30,9 +30,9 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Universal.New). Tap(func() { branchName := "my-branch-name" - input.ExpectPrompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() + t.ExpectPrompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() - input.Model().CurrentBranchName(branchName) + t.Model().CurrentBranchName(branchName) }). Lines( Contains("commit 2"), diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index 23cb5cb8e..c2f3b9a52 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -15,17 +15,17 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ shell.GitAddAll() shell.Commit("first commit") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(1) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(1) - input.Views().Commits(). + t.Views().Commits(). Focus(). Lines( Contains("first commit"), ). Press(keys.Commits.RevertCommit). Tap(func() { - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Revert commit")). Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). Confirm() @@ -35,7 +35,7 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ Contains("first commit"), ) - input.Views().Main().Content(Contains("-myfile content")) - input.FileSystem().PathNotPresent("myfile") + t.Views().Main().Content(Contains("-myfile content")) + t.FileSystem().PathNotPresent("myfile") }, }) diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index 4e5dacd0b..559231f53 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -15,41 +15,41 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(0) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). SelectedLine(Contains("myfile")). PressPrimaryAction(). // stage the file PressEnter() - input.Views().StagingSecondary(). + t.Views().StagingSecondary(). IsFocused(). Tap(func() { // we start with both lines having been staged - input.Views().StagingSecondary().Content(Contains("+myfile content")) - input.Views().StagingSecondary().Content(Contains("+with a second line")) - input.Views().Staging().Content(DoesNotContain("+myfile content")) - input.Views().Staging().Content(DoesNotContain("+with a second line")) + t.Views().StagingSecondary().Content(Contains("+myfile content")) + t.Views().StagingSecondary().Content(Contains("+with a second line")) + t.Views().Staging().Content(DoesNotContain("+myfile content")) + t.Views().Staging().Content(DoesNotContain("+with a second line")) }). // unstage the selected line PressPrimaryAction(). Tap(func() { // the line should have been moved to the main view - input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) - input.Views().StagingSecondary().Content(Contains("+with a second line")) - input.Views().Staging().Content(Contains("+myfile content")) - input.Views().Staging().Content(DoesNotContain("+with a second line")) + t.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) + t.Views().StagingSecondary().Content(Contains("+with a second line")) + t.Views().Staging().Content(Contains("+myfile content")) + t.Views().Staging().Content(DoesNotContain("+with a second line")) }). Press(keys.Files.CommitChanges) commitMessage := "my commit message" - input.ExpectCommitMessagePanel().Type(commitMessage).Confirm() + t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - input.Model().CommitCount(1) - input.Model().HeadCommitMessage(Equals(commitMessage)) - input.Views().StagingSecondary().IsFocused() + t.Model().CommitCount(1) + t.Model().HeadCommitMessage(Equals(commitMessage)) + t.Views().StagingSecondary().IsFocused() // 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 9b46f4259..be0d43904 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -15,41 +15,41 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(0) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(0) // stage the file - input.Views().Files(). + t.Views().Files(). IsFocused(). SelectedLine(Contains("myfile")). PressPrimaryAction(). PressEnter() // we start with both lines having been staged - input.Views().StagingSecondary().Content( + t.Views().StagingSecondary().Content( Contains("+myfile content").Contains("+with a second line"), ) - input.Views().Staging().Content( + t.Views().Staging().Content( DoesNotContain("+myfile content").DoesNotContain("+with a second line"), ) // unstage the selected line - input.Views().StagingSecondary(). + t.Views().StagingSecondary(). IsFocused(). PressPrimaryAction(). Tap(func() { // the line should have been moved to the main view - input.Views().Staging().Content(Contains("+myfile content").DoesNotContain("+with a second line")) + t.Views().Staging().Content(Contains("+myfile content").DoesNotContain("+with a second line")) }). Content(DoesNotContain("+myfile content").Contains("+with a second line")). Press(keys.Files.CommitChangesWithoutHook) commitMessage := ": my commit message" - input.ExpectCommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() + t.ExpectCommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() - input.Model().CommitCount(1) - input.Model().HeadCommitMessage(Equals("WIP" + commitMessage)) - input.Views().StagingSecondary().IsFocused() + t.Model().CommitCount(1) + t.Model().HeadCommitMessage(Equals("WIP" + commitMessage)) + t.Views().StagingSecondary().IsFocused() // 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 2d6ba8b8a..69eb4e814 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -5,7 +5,7 @@ import ( . "github.com/jesseduffield/lazygit/pkg/integration/components" ) -// TODO: find out why we can't use input.SelectedLine() on the staging/stagingSecondary views. +// TODO: find out why we can't use .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", @@ -17,33 +17,33 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(0) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). SelectedLine(Contains("myfile")). PressEnter() - input.Views().Staging(). + t.Views().Staging(). IsFocused(). Tap(func() { - input.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) + t.Views().StagingSecondary().Content(DoesNotContain("+myfile content")) }). // stage the first line PressPrimaryAction(). Tap(func() { - input.Views().Staging().Content(DoesNotContain("+myfile content")) - input.Views().StagingSecondary().Content(Contains("+myfile content")) + t.Views().Staging().Content(DoesNotContain("+myfile content")) + t.Views().StagingSecondary().Content(Contains("+myfile content")) }). Press(keys.Files.CommitChanges) commitMessage := "my commit message" - input.ExpectCommitMessagePanel().Type(commitMessage).Confirm() + t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - input.Model().CommitCount(1) - input.Model().HeadCommitMessage(Equals(commitMessage)) - input.Views().Staging().IsFocused() + t.Model().CommitCount(1) + t.Model().HeadCommitMessage(Equals(commitMessage)) + t.Views().Staging().IsFocused() // TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed) }, diff --git a/pkg/integration/tests/config/remote_named_star.go b/pkg/integration/tests/config/remote_named_star.go index 1796cab20..3cba2fd8a 100644 --- a/pkg/integration/tests/config/remote_named_star.go +++ b/pkg/integration/tests/config/remote_named_star.go @@ -17,10 +17,10 @@ var RemoteNamedStar = NewIntegrationTest(NewIntegrationTestArgs{ SetupConfig: func(cfg *config.AppConfig) {}, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { // here we're just asserting that we haven't panicked upon starting lazygit - input.Model().AtLeastOneCommit() + t.Model().AtLeastOneCommit() }, }) diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go index 2317525ac..fd20f79e6 100644 --- a/pkg/integration/tests/custom_commands/basic.go +++ b/pkg/integration/tests/custom_commands/basic.go @@ -23,12 +23,12 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { - input.Model().WorkingTreeFileCount(0) + t.Model().WorkingTreeFileCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). Press("a"). Lines( diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index e07f57450..9ede837ce 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -57,26 +57,26 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { - input.Model().WorkingTreeFileCount(0) + t.Model().WorkingTreeFileCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). Press("a") - input.ExpectPrompt().Title(Equals("Enter a file name")).Type("my file").Confirm() + t.ExpectPrompt().Title(Equals("Enter a file name")).Type("my file").Confirm() - input.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() + t.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - input.Model().WorkingTreeFileCount(1) - input.Views().Files().SelectedLine(Contains("my file")) - input.Views().Main().Content(Contains(`"BAR"`)) + t.Model().WorkingTreeFileCount(1) + t.Views().Files().SelectedLine(Contains("my file")) + t.Views().Main().Content(Contains(`"BAR"`)) }, }) diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index 6af2a663f..77d6621db 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -44,21 +44,21 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { - input.Model().WorkingTreeFileCount(0) - input.Views().Branches(). + t.Model().WorkingTreeFileCount(0) + t.Views().Branches(). Focus(). Press("a") - input.ExpectMenu().Title(Equals("Choose commit message")).Select(Contains("bar")).Confirm() + t.ExpectMenu().Title(Equals("Choose commit message")).Select(Contains("bar")).Confirm() - input.ExpectPrompt().Title(Equals("Description")).Type(" my branch").Confirm() + t.ExpectPrompt().Title(Equals("Description")).Type(" my branch").Confirm() - input.Model().WorkingTreeFileCount(1) + t.Model().WorkingTreeFileCount(1) - input.Views().Files().Focus().SelectedLine(Contains("output.txt")) - input.Views().Main().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) + t.Views().Files().Focus().SelectedLine(Contains("output.txt")) + t.Views().Main().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) }, }) 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 2877ab006..c64b35e6e 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -43,23 +43,23 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { - input.Model().CurrentBranchName("feature/bar") - input.Model().WorkingTreeFileCount(0) + t.Model().CurrentBranchName("feature/bar") + t.Model().WorkingTreeFileCount(0) - input.Views().Branches(). + t.Views().Branches(). Focus(). Press("a") - input.ExpectPrompt(). + t.ExpectPrompt(). Title(Equals("Which git command do you want to run?")). InitialText(Equals("branch")). Confirm() - input.ExpectMenu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() + t.ExpectMenu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() - input.Model().CurrentBranchName("master") + t.Model().CurrentBranchName("master") }, }) diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index 4f94cb28d..9bdcc2e11 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -55,26 +55,26 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func( shell *Shell, - input *Input, + t *TestDriver, keys config.KeybindingConfig, ) { - input.Model().WorkingTreeFileCount(0) + t.Model().WorkingTreeFileCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). Press("a") - input.ExpectPrompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() + t.ExpectPrompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() - input.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() + t.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - input.Model().WorkingTreeFileCount(1) - input.Views().Files().SelectedLine(Contains("myfile")) - input.Views().Main().Content(Contains("BAR")) + t.Model().WorkingTreeFileCount(1) + t.Views().Files().SelectedLine(Contains("myfile")) + t.Views().Main().Content(Contains("BAR")) }, }) diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index a30a50589..d8f679aa0 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -21,8 +21,8 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("branch-a") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). TopLines( Contains("branch-a"), @@ -30,44 +30,44 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.DiffingMenu) - input.ExpectMenu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() + t.ExpectMenu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() - input.Views().Branches(). + t.Views().Branches(). IsFocused(). Tap(func() { - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) + t.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) }). SelectNextItem(). Tap(func() { - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) - input.Views().Main().Content(Contains("+second line")) + t.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) + t.Views().Main().Content(Contains("+second line")) }). PressEnter() - input.Views().SubCommits(). + t.Views().SubCommits(). IsFocused(). SelectedLine(Contains("update")). Tap(func() { - input.Views().Main().Content(Contains("+second line")) + t.Views().Main().Content(Contains("+second line")) }). PressEnter() - input.Views().CommitFiles(). + t.Views().CommitFiles(). IsFocused(). SelectedLine(Contains("file1")). Tap(func() { - input.Views().Main().Content(Contains("+second line")) + t.Views().Main().Content(Contains("+second line")) }). PressEscape() - input.Views().SubCommits().PressEscape() + t.Views().SubCommits().PressEscape() - input.Views().Branches(). + t.Views().Branches(). IsFocused(). Press(keys.Universal.DiffingMenu) - input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b -R")) - input.Views().Main().Content(Contains("-second line")) + t.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() + t.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b -R")) + t.Views().Main().Content(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 65bb27ebd..4777a92da 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -21,8 +21,8 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("branch-a") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Branches(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). Focus(). Lines( Contains("branch-a"), @@ -30,49 +30,49 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.DiffingMenu) - input.ExpectMenu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() + t.ExpectMenu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) + t.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) - input.Views().Branches(). + t.Views().Branches(). IsFocused(). SelectNextItem(). Tap(func() { - input.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) - input.Views().Main().Content(Contains("+second line")) + t.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b")) + t.Views().Main().Content(Contains("+second line")) }). PressEnter() - input.Views().SubCommits(). + t.Views().SubCommits(). IsFocused(). SelectedLine(Contains("update")). Tap(func() { - input.Views().Main().Content(Contains("+second line")) + t.Views().Main().Content(Contains("+second line")) }). PressEnter() - input.Views().CommitFiles(). + t.Views().CommitFiles(). IsFocused(). SelectedLine(Contains("file1")). Tap(func() { - input.Views().Main().Content(Contains("+second line")) + t.Views().Main().Content(Contains("+second line")) }). PressPrimaryAction(). // add the file to the patch Press(keys.Universal.DiffingMenu). Tap(func() { - input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() + t.ExpectMenu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() - input.Views().Information().Content(DoesNotContain("building patch")) + t.Views().Information().Content(DoesNotContain("building patch")) }). Press(keys.Universal.CreatePatchOptionsMenu) // adding the regex '$' here to distinguish the menu item from the 'apply patch in reverse' item - input.ExpectMenu().Title(Equals("Patch Options")).Select(MatchesRegexp("apply patch$")).Confirm() + t.ExpectMenu().Title(Equals("Patch Options")).Select(MatchesRegexp("apply patch$")).Confirm() - input.Views().Files(). + t.Views().Files(). Focus(). SelectedLine(Contains("file1")) - input.Views().Main().Content(Contains("+second line")) + t.Views().Main().Content(Contains("+second line")) }, }) diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index c8091a17e..d67dcf3a6 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -18,8 +18,8 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ shell.UpdateFileAndAdd("file1", "first line\nsecond line\nthird line\n") shell.Commit("third commit") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Commits(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). Focus(). Lines( Contains("third commit").IsSelected(), @@ -28,28 +28,28 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.DiffingMenu). Tap(func() { - input.ExpectMenu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() + t.ExpectMenu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() - input.Views().Information().Content(Contains("showing output for: git diff")) + t.Views().Information().Content(Contains("showing output for: git diff")) }). SelectNextItem(). SelectNextItem(). SelectedLine(Contains("first commit")). Tap(func() { - input.Views().Main().Content(Contains("-second line\n-third line")) + t.Views().Main().Content(Contains("-second line\n-third line")) }). Press(keys.Universal.DiffingMenu). Tap(func() { - input.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() + t.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() - input.Views().Main().Content(Contains("+second line\n+third line")) + t.Views().Main().Content(Contains("+second line\n+third line")) }). PressEnter() - input.Views().CommitFiles(). + t.Views().CommitFiles(). IsFocused(). SelectedLine(Contains("file1")) - input.Views().Main().Content(Contains("+second line\n+third line")) + t.Views().Main().Content(Contains("+second line\n+third line")) }, }) diff --git a/pkg/integration/tests/file/dir_with_untracked_file.go b/pkg/integration/tests/file/dir_with_untracked_file.go index be0e7022e..56128aabb 100644 --- a/pkg/integration/tests/file/dir_with_untracked_file.go +++ b/pkg/integration/tests/file/dir_with_untracked_file.go @@ -21,10 +21,10 @@ var DirWithUntrackedFile = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("dir/untracked", "bar") shell.UpdateFile("dir/file", "baz") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(1) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(1) - input.Views().Main(). + t.Views().Main(). Content(DoesNotContain("error: Could not access")). // we show baz because it's a modified file but we don't show bar because it's untracked // (though it would be cool if we could show that too) diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index b36b9a0ab..785d8558e 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -71,8 +71,8 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ shell.RunShellCommand(`echo "renamed\nhaha" > renamed2.txt && git add renamed2.txt`) }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(3) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(3) type statusFile struct { status string @@ -82,12 +82,12 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ discardOneByOne := func(files []statusFile) { for _, file := range files { - input.Views().Files(). + t.Views().Files(). IsFocused(). SelectedLine(Contains(file.status + " " + file.label)). Press(keys.Universal.Remove) - input.ExpectMenu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() + t.ExpectMenu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() } } @@ -101,7 +101,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"}, }) - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Cancel() @@ -121,6 +121,6 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "??", label: "new.txt", menuTitle: "new.txt"}, }) - input.Model().WorkingTreeFileCount(0) + t.Model().WorkingTreeFileCount(0) }, }) diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 8fcb850c6..76639ef46 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -27,27 +27,27 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ Merge("feature-branch"). CreateFileAndAdd(postMergeFilename, postMergeFileContent) }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(3) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(3) mergeCommitMessage := "Merge branch 'feature-branch' into development-branch" - input.Model().HeadCommitMessage(Contains(mergeCommitMessage)) + t.Model().HeadCommitMessage(Contains(mergeCommitMessage)) - input.Views().Commits(). + t.Views().Commits(). Focus(). Press(keys.Commits.AmendToCommit) - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("Amend Commit")). Content(Contains("Are you sure you want to amend this commit with your staged files?")). Confirm() // assuring we haven't added a brand new commit - input.Model().CommitCount(3) - input.Model().HeadCommitMessage(Contains(mergeCommitMessage)) + t.Model().CommitCount(3) + t.Model().HeadCommitMessage(Contains(mergeCommitMessage)) // assuring the post-merge file shows up in the merge commit. - input.Views().Main(). + t.Views().Main(). Content(Contains(postMergeFilename)). Content(Contains("++" + postMergeFileContent)) }, diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go index 5e091f7fc..909dd7a82 100644 --- a/pkg/integration/tests/interactive_rebase/one.go +++ b/pkg/integration/tests/interactive_rebase/one.go @@ -14,8 +14,8 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ shell. CreateNCommits(5) // these will appears at commit 05, 04, 04, down to 01 }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Commits(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). Focus(). Lines( Contains("commit 05"), @@ -61,7 +61,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 01"), ). Tap(func() { - input.ContinueRebase() + t.ContinueRebase() }). Lines( Contains("commit 02"), diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index 0cb833046..6699d2db3 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -13,14 +13,14 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ config.UserConfig.ConfirmOnQuit = true }, SetupRepo: func(shell *Shell) {}, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().CommitCount(0) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().CommitCount(0) - input.Views().Files(). + t.Views().Files(). IsFocused(). Press(keys.Universal.Quit) - input.ExpectConfirmation(). + t.ExpectConfirmation(). Title(Equals("")). Content(Contains("Are you sure you want to quit?")). Confirm() diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index d18ea6f38..5f48c80a2 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -18,8 +18,8 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ CreateFileAndAdd("file-2", "change to stash2"). StashWithMessage("bar") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Views().Stash(). + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Views().Stash(). Focus(). Lines( Equals("On master: bar"), @@ -28,7 +28,7 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Stash.RenameStash). Tap(func() { - input.ExpectPrompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() + t.ExpectPrompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() }). SelectedLine(Equals("On master: foo baz")) }, diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index 34e376886..16c51537a 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -15,18 +15,18 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("file", "content") shell.GitAddAll() }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().StashCount(0) - input.Model().WorkingTreeFileCount(1) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().StashCount(0) + t.Model().WorkingTreeFileCount(1) - input.Views().Files(). + t.Views().Files(). Press(keys.Files.ViewStashOptions) - input.ExpectMenu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() + t.ExpectMenu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() - input.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() + t.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - input.Model().StashCount(1) - input.Model().WorkingTreeFileCount(0) + t.Model().StashCount(1) + t.Model().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 d923aca3a..cc38f2ee8 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -16,18 +16,18 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("file_2", "content") shell.GitAdd("file_1") }, - Run: func(shell *Shell, input *Input, keys config.KeybindingConfig) { - input.Model().StashCount(0) - input.Model().WorkingTreeFileCount(2) + Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + t.Model().StashCount(0) + t.Model().WorkingTreeFileCount(2) - input.Views().Files(). + t.Views().Files(). Press(keys.Files.ViewStashOptions) - input.ExpectMenu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() + t.ExpectMenu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() - input.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() + t.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - input.Model().StashCount(1) - input.Model().WorkingTreeFileCount(0) + t.Model().StashCount(1) + t.Model().WorkingTreeFileCount(0) }, }) From c5050ecabd57702c7bfb02a38729ed8a4f23b2c5 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 21:47:37 +1100 Subject: [PATCH 11/20] move shell into test driver --- pkg/integration/components/runner.go | 2 +- pkg/integration/components/shell.go | 109 +++++++++--------- pkg/integration/components/test.go | 13 +-- pkg/integration/components/test_driver.go | 9 +- pkg/integration/components/test_test.go | 6 +- pkg/integration/tests/bisect/basic.go | 6 +- .../tests/bisect/from_other_branch.go | 6 +- .../tests/branch/checkout_by_name.go | 2 +- pkg/integration/tests/branch/delete.go | 2 +- pkg/integration/tests/branch/rebase.go | 2 +- .../tests/branch/rebase_and_drop.go | 2 +- pkg/integration/tests/branch/reset.go | 2 +- pkg/integration/tests/branch/suggestions.go | 2 +- .../tests/cherry_pick/cherry_pick.go | 2 +- .../cherry_pick/cherry_pick_conflicts.go | 2 +- pkg/integration/tests/commit/commit.go | 2 +- .../tests/commit/commit_multiline.go | 2 +- pkg/integration/tests/commit/new_branch.go | 2 +- pkg/integration/tests/commit/revert.go | 2 +- pkg/integration/tests/commit/staged.go | 2 +- .../tests/commit/staged_without_hooks.go | 2 +- pkg/integration/tests/commit/unstaged.go | 2 +- .../tests/config/remote_named_star.go | 6 +- .../tests/custom_commands/basic.go | 6 +- .../tests/custom_commands/form_prompts.go | 6 +- .../custom_commands/menu_from_command.go | 6 +- .../menu_from_commands_output.go | 6 +- .../tests/custom_commands/multiple_prompts.go | 6 +- pkg/integration/tests/diff/diff.go | 2 +- .../tests/diff/diff_and_apply_patch.go | 2 +- pkg/integration/tests/diff/diff_commits.go | 2 +- .../tests/file/dir_with_untracked_file.go | 2 +- pkg/integration/tests/file/discard_changes.go | 2 +- .../tests/interactive_rebase/amend_merge.go | 2 +- .../tests/interactive_rebase/one.go | 2 +- pkg/integration/tests/misc/confirm_on_quit.go | 2 +- pkg/integration/tests/stash/rename.go | 2 +- pkg/integration/tests/stash/stash.go | 2 +- .../stash/stash_including_untracked_files.go | 2 +- 39 files changed, 108 insertions(+), 131 deletions(-) diff --git a/pkg/integration/components/runner.go b/pkg/integration/components/runner.go index 85ea3f330..964ad98a5 100644 --- a/pkg/integration/components/runner.go +++ b/pkg/integration/components/runner.go @@ -126,7 +126,7 @@ func buildLazygit() error { } func createFixture(test *IntegrationTest, paths Paths) error { - shell := NewShell(paths.ActualRepo()) + shell := NewShell(paths.ActualRepo(), func(errorMsg string) { panic(errorMsg) }) shell.RunCommand("git init -b master") shell.RunCommand(`git config user.email "CI@example.com"`) shell.RunCommand(`git config user.name "CI"`) diff --git a/pkg/integration/components/shell.go b/pkg/integration/components/shell.go index d0f0345dc..3fd63c8cc 100644 --- a/pkg/integration/components/shell.go +++ b/pkg/integration/components/shell.go @@ -15,119 +15,122 @@ import ( type Shell struct { // working directory the shell is invoked in dir string + // when running the shell outside the gui we can directly panic on failure, + // but inside the gui we need to close the gui before panicking + fail func(string) } -func NewShell(dir string) *Shell { - return &Shell{dir: dir} +func NewShell(dir string, fail func(string)) *Shell { + return &Shell{dir: dir, fail: fail} } -func (s *Shell) RunCommand(cmdStr string) *Shell { +func (self *Shell) RunCommand(cmdStr string) *Shell { args := str.ToArgv(cmdStr) cmd := secureexec.Command(args[0], args[1:]...) cmd.Env = os.Environ() - cmd.Dir = s.dir + cmd.Dir = self.dir output, err := cmd.CombinedOutput() if err != nil { - panic(fmt.Sprintf("error running command: %s\n%s", cmdStr, string(output))) + self.fail(fmt.Sprintf("error running command: %s\n%s", cmdStr, string(output))) } - return s + return self } -func (s *Shell) RunShellCommand(cmdStr string) *Shell { +func (self *Shell) RunShellCommand(cmdStr string) *Shell { cmd := secureexec.Command("sh", "-c", cmdStr) cmd.Env = os.Environ() - cmd.Dir = s.dir + cmd.Dir = self.dir output, err := cmd.CombinedOutput() if err != nil { - panic(fmt.Sprintf("error running shell command: %s\n%s", cmdStr, string(output))) + self.fail(fmt.Sprintf("error running shell command: %s\n%s", cmdStr, string(output))) } - return s + return self } -func (s *Shell) RunShellCommandExpectError(cmdStr string) *Shell { +func (self *Shell) RunShellCommandExpectError(cmdStr string) *Shell { cmd := secureexec.Command("sh", "-c", cmdStr) cmd.Env = os.Environ() - cmd.Dir = s.dir + cmd.Dir = self.dir output, err := cmd.CombinedOutput() if err == nil { - panic(fmt.Sprintf("Expected error running shell command: %s\n%s", cmdStr, string(output))) + self.fail(fmt.Sprintf("Expected error running shell command: %s\n%s", cmdStr, string(output))) } - return s + return self } -func (s *Shell) CreateFile(path string, content string) *Shell { - fullPath := filepath.Join(s.dir, path) +func (self *Shell) CreateFile(path string, content string) *Shell { + fullPath := filepath.Join(self.dir, path) err := os.WriteFile(fullPath, []byte(content), 0o644) if err != nil { - panic(fmt.Sprintf("error creating file: %s\n%s", fullPath, err)) + self.fail(fmt.Sprintf("error creating file: %s\n%s", fullPath, err)) } - return s + return self } -func (s *Shell) CreateDir(path string) *Shell { - fullPath := filepath.Join(s.dir, path) +func (self *Shell) CreateDir(path string) *Shell { + fullPath := filepath.Join(self.dir, path) if err := os.MkdirAll(fullPath, 0o755); err != nil { - panic(fmt.Sprintf("error creating directory: %s\n%s", fullPath, err)) + self.fail(fmt.Sprintf("error creating directory: %s\n%s", fullPath, err)) } - return s + return self } -func (s *Shell) UpdateFile(path string, content string) *Shell { - fullPath := filepath.Join(s.dir, path) +func (self *Shell) UpdateFile(path string, content string) *Shell { + fullPath := filepath.Join(self.dir, path) err := os.WriteFile(fullPath, []byte(content), 0o644) if err != nil { - panic(fmt.Sprintf("error updating file: %s\n%s", fullPath, err)) + self.fail(fmt.Sprintf("error updating file: %s\n%s", fullPath, err)) } - return s + return self } -func (s *Shell) NewBranch(name string) *Shell { - return s.RunCommand("git checkout -b " + name) +func (self *Shell) NewBranch(name string) *Shell { + return self.RunCommand("git checkout -b " + name) } -func (s *Shell) Checkout(name string) *Shell { - return s.RunCommand("git checkout " + name) +func (self *Shell) Checkout(name string) *Shell { + return self.RunCommand("git checkout " + name) } -func (s *Shell) Merge(name string) *Shell { - return s.RunCommand("git merge --commit --no-ff " + name) +func (self *Shell) Merge(name string) *Shell { + return self.RunCommand("git merge --commit --no-ff " + name) } -func (s *Shell) GitAdd(path string) *Shell { - return s.RunCommand(fmt.Sprintf("git add \"%s\"", path)) +func (self *Shell) GitAdd(path string) *Shell { + return self.RunCommand(fmt.Sprintf("git add \"%s\"", path)) } -func (s *Shell) GitAddAll() *Shell { - return s.RunCommand("git add -A") +func (self *Shell) GitAddAll() *Shell { + return self.RunCommand("git add -A") } -func (s *Shell) Commit(message string) *Shell { - return s.RunCommand(fmt.Sprintf("git commit -m \"%s\"", message)) +func (self *Shell) Commit(message string) *Shell { + return self.RunCommand(fmt.Sprintf("git commit -m \"%s\"", message)) } -func (s *Shell) EmptyCommit(message string) *Shell { - return s.RunCommand(fmt.Sprintf("git commit --allow-empty -m \"%s\"", message)) +func (self *Shell) EmptyCommit(message string) *Shell { + return self.RunCommand(fmt.Sprintf("git commit --allow-empty -m \"%s\"", message)) } // convenience method for creating a file and adding it -func (s *Shell) CreateFileAndAdd(fileName string, fileContents string) *Shell { - return s. +func (self *Shell) CreateFileAndAdd(fileName string, fileContents string) *Shell { + return self. CreateFile(fileName, fileContents). GitAdd(fileName) } // convenience method for updating a file and adding it -func (s *Shell) UpdateFileAndAdd(fileName string, fileContents string) *Shell { - return s. +func (self *Shell) UpdateFileAndAdd(fileName string, fileContents string) *Shell { + return self. UpdateFile(fileName, fileContents). GitAdd(fileName) } @@ -135,24 +138,24 @@ func (s *Shell) UpdateFileAndAdd(fileName string, fileContents string) *Shell { // creates commits 01, 02, 03, ..., n with a new file in each // The reason for padding with zeroes is so that it's easier to do string // matches on the commit messages when there are many of them -func (s *Shell) CreateNCommits(n int) *Shell { +func (self *Shell) CreateNCommits(n int) *Shell { for i := 1; i <= n; i++ { - s.CreateFileAndAdd( + self.CreateFileAndAdd( fmt.Sprintf("file%02d.txt", i), fmt.Sprintf("file%02d content", i), ). Commit(fmt.Sprintf("commit %02d", i)) } - return s + return self } -func (s *Shell) StashWithMessage(message string) *Shell { - s.RunCommand(fmt.Sprintf(`git stash -m "%s"`, message)) - return s +func (self *Shell) StashWithMessage(message string) *Shell { + self.RunCommand(fmt.Sprintf(`git stash -m "%s"`, message)) + return self } -func (s *Shell) SetConfig(key string, value string) *Shell { - s.RunCommand(fmt.Sprintf(`git config --local "%s" %s`, key, value)) - return s +func (self *Shell) SetConfig(key string, value string) *Shell { + self.RunCommand(fmt.Sprintf(`git config --local "%s" %s`, key, value)) + return self } diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go index 927dfb36c..0b36a12d9 100644 --- a/pkg/integration/components/test.go +++ b/pkg/integration/components/test.go @@ -24,8 +24,7 @@ type IntegrationTest struct { setupRepo func(shell *Shell) setupConfig func(config *config.AppConfig) run func( - shell *Shell, - testController *TestDriver, + testDriver *TestDriver, keys config.KeybindingConfig, ) } @@ -40,7 +39,7 @@ type NewIntegrationTestArgs struct { // takes a config and mutates. The mutated context will end up being passed to the gui SetupConfig func(config *config.AppConfig) // runs the test - Run func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) + Run func(t *TestDriver, keys config.KeybindingConfig) // additional args passed to lazygit ExtraCmdArgs string // for when a test is flakey @@ -92,15 +91,15 @@ func (self *IntegrationTest) SetupRepo(shell *Shell) { // I want access to all contexts, the model, the ability to press a key, the ability to log, func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) { - shell := NewShell("/tmp/lazygit-test") + shell := NewShell("/tmp/lazygit-test", func(errorMsg string) { gui.Fail(errorMsg) }) keys := gui.Keys() - testController := NewTestController(gui, keys, KeyPressDelay()) + testDriver := NewTestDriver(gui, shell, keys, KeyPressDelay()) - self.run(shell, testController, keys) + self.run(testDriver, keys) if KeyPressDelay() > 0 { // the dev would want to see the final state if they're running in slow mode - testController.Wait(2000) + testDriver.Wait(2000) } } diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index 7b3fb0889..f2604d211 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -16,14 +16,16 @@ type TestDriver struct { keys config.KeybindingConfig pushKeyDelay int *assertionHelper + shell *Shell } -func NewTestController(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, pushKeyDelay int) *TestDriver { +func NewTestDriver(gui integrationTypes.GuiDriver, shell *Shell, keys config.KeybindingConfig, pushKeyDelay int) *TestDriver { return &TestDriver{ gui: gui, keys: keys, pushKeyDelay: pushKeyDelay, assertionHelper: &assertionHelper{gui: gui}, + shell: shell, } } @@ -67,6 +69,11 @@ func (self *TestDriver) Log(message string) { self.gui.LogUI(message) } +// allows the user to run shell commands during the test to emulate background activity +func (self *TestDriver) Shell() *Shell { + return self.shell +} + // this will look for a list item in the current panel and if it finds it, it will // enter the keypresses required to navigate to it. // The test will fail if: diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index 79d2b3955..ccab35dc8 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -63,7 +63,7 @@ func (self *fakeGuiDriver) View(viewName string) *gocui.View { func TestAssertionFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.press("a") t.press("b") t.Model().CommitCount(2) @@ -78,7 +78,7 @@ func TestAssertionFailure(t *testing.T) { func TestManualFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Fail("blah") }, }) @@ -90,7 +90,7 @@ func TestManualFailure(t *testing.T) { func TestSuccess(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.press("a") t.press("b") t.Model().CommitCount(0) diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index cbb37aac7..8294f61a4 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -14,11 +14,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ CreateNCommits(10) }, SetupConfig: func(cfg *config.AppConfig) {}, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { markCommitAsBad := func() { t.Views().Commits(). Press(keys.Commits.ViewBisectOptions) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 8759e28f3..13e7e8055 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -18,11 +18,7 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ RunCommand("git bisect start other~2 other~5") }, SetupConfig: func(cfg *config.AppConfig) {}, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Information().Content(Contains("bisecting")) t.Model().AtLeastOneCommit() diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index 7a8733d26..c786f8970 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -17,7 +17,7 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ Checkout("master"). EmptyCommit("blah") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). Lines( diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 6410576e8..520923cd6 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -16,7 +16,7 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ NewBranch("branch-one"). NewBranch("branch-two") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). Lines( diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index b90810b82..137bada27 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -14,7 +14,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Commits().TopLines( Contains("first change"), Contains("original"), diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 610bb1c19..dc1cfddea 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -17,7 +17,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ shell.EmptyCommit("to remove") shell.EmptyCommit("to keep") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). Lines( diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index bfd1b950f..65a10e31b 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -20,7 +20,7 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("current-branch") shell.EmptyCommit("current-branch commit") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Commits().Lines( Contains("current-branch commit"), Contains("root commit"), diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index 438bbf9be..65c64fa6d 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -20,7 +20,7 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ NewBranch("other-new-branch-2"). NewBranch("other-new-branch-3") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). Press(keys.Branches.CheckoutBranchByName) diff --git a/pkg/integration/tests/cherry_pick/cherry_pick.go b/pkg/integration/tests/cherry_pick/cherry_pick.go index 5fa2d47ac..a9d7dd9c7 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -23,7 +23,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("four"). Checkout("first-branch") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). Lines( diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index 5de63baa6..5eef30b50 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -14,7 +14,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). Lines( diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index 951529cea..5950545e7 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -14,7 +14,7 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("myfile", "myfile content") shell.CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index 823412f68..11876e09a 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -13,7 +13,7 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ SetupRepo: func(shell *Shell) { shell.CreateFile("myfile", "myfile content") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index f2deecdc9..6f528ff4c 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -16,7 +16,7 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("commit 2"). EmptyCommit("commit 3") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(3) t.Views().Commits(). diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index c2f3b9a52..bee657380 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -15,7 +15,7 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ shell.GitAddAll() shell.Commit("first commit") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(1) t.Views().Commits(). diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index 559231f53..d0698192a 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -15,7 +15,7 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/commit/staged_without_hooks.go b/pkg/integration/tests/commit/staged_without_hooks.go index be0d43904..8a6b0d3d0 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -15,7 +15,7 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(0) // stage the file diff --git a/pkg/integration/tests/commit/unstaged.go b/pkg/integration/tests/commit/unstaged.go index 69eb4e814..3e0d68617 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -17,7 +17,7 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile", "myfile content\nwith a second line"). CreateFile("myfile2", "myfile2 content") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/config/remote_named_star.go b/pkg/integration/tests/config/remote_named_star.go index 3cba2fd8a..0306427ca 100644 --- a/pkg/integration/tests/config/remote_named_star.go +++ b/pkg/integration/tests/config/remote_named_star.go @@ -15,11 +15,7 @@ var RemoteNamedStar = NewIntegrationTest(NewIntegrationTestArgs{ CreateNCommits(2) }, SetupConfig: func(cfg *config.AppConfig) {}, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { // here we're just asserting that we haven't panicked upon starting lazygit t.Model().AtLeastOneCommit() }, diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go index fd20f79e6..a73fab5a9 100644 --- a/pkg/integration/tests/custom_commands/basic.go +++ b/pkg/integration/tests/custom_commands/basic.go @@ -21,11 +21,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ }, } }, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().WorkingTreeFileCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index 9ede837ce..b35455368 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -55,11 +55,7 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ }, } }, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().WorkingTreeFileCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index 77d6621db..580022521 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -42,11 +42,7 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ }, } }, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().WorkingTreeFileCount(0) t.Views().Branches(). Focus(). 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 c64b35e6e..a9a899341 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -41,11 +41,7 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ }, } }, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CurrentBranchName("feature/bar") t.Model().WorkingTreeFileCount(0) diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index 9bdcc2e11..fa69169aa 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -53,11 +53,7 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ }, } }, - Run: func( - shell *Shell, - t *TestDriver, - keys config.KeybindingConfig, - ) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().WorkingTreeFileCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index d8f679aa0..7d66cc49d 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -21,7 +21,7 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("branch-a") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). TopLines( diff --git a/pkg/integration/tests/diff/diff_and_apply_patch.go b/pkg/integration/tests/diff/diff_and_apply_patch.go index 4777a92da..94cd29a6c 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -21,7 +21,7 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ shell.Checkout("branch-a") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). Focus(). Lines( diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index d67dcf3a6..68d4e99fd 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -18,7 +18,7 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ shell.UpdateFileAndAdd("file1", "first line\nsecond line\nthird line\n") shell.Commit("third commit") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Commits(). Focus(). Lines( diff --git a/pkg/integration/tests/file/dir_with_untracked_file.go b/pkg/integration/tests/file/dir_with_untracked_file.go index 56128aabb..e94d237d9 100644 --- a/pkg/integration/tests/file/dir_with_untracked_file.go +++ b/pkg/integration/tests/file/dir_with_untracked_file.go @@ -21,7 +21,7 @@ var DirWithUntrackedFile = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("dir/untracked", "bar") shell.UpdateFile("dir/file", "baz") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(1) t.Views().Main(). diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index 785d8558e..ab08ff9b9 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -71,7 +71,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ shell.RunShellCommand(`echo "renamed\nhaha" > renamed2.txt && git add renamed2.txt`) }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(3) type statusFile struct { diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 76639ef46..1f09af0de 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -27,7 +27,7 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ Merge("feature-branch"). CreateFileAndAdd(postMergeFilename, postMergeFileContent) }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(3) mergeCommitMessage := "Merge branch 'feature-branch' into development-branch" diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go index 909dd7a82..fdfc2db52 100644 --- a/pkg/integration/tests/interactive_rebase/one.go +++ b/pkg/integration/tests/interactive_rebase/one.go @@ -14,7 +14,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ shell. CreateNCommits(5) // these will appears at commit 05, 04, 04, down to 01 }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Commits(). Focus(). Lines( diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index 6699d2db3..109ece2c9 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -13,7 +13,7 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ config.UserConfig.ConfirmOnQuit = true }, SetupRepo: func(shell *Shell) {}, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().CommitCount(0) t.Views().Files(). diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index 5f48c80a2..fded5041c 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -18,7 +18,7 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ CreateFileAndAdd("file-2", "change to stash2"). StashWithMessage("bar") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Stash(). Focus(). Lines( diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index 16c51537a..4265e0c23 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -15,7 +15,7 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("file", "content") shell.GitAddAll() }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().StashCount(0) t.Model().WorkingTreeFileCount(1) diff --git a/pkg/integration/tests/stash/stash_including_untracked_files.go b/pkg/integration/tests/stash/stash_including_untracked_files.go index cc38f2ee8..d46d7fb1d 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -16,7 +16,7 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("file_2", "content") shell.GitAdd("file_1") }, - Run: func(shell *Shell, t *TestDriver, keys config.KeybindingConfig) { + Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Model().StashCount(0) t.Model().WorkingTreeFileCount(2) From ed93e0a2b0943379470049d2a25e4fb828179b97 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 27 Dec 2022 22:52:20 +1100 Subject: [PATCH 12/20] remove dependency on model --- pkg/gui/gui_driver.go | 4 - pkg/integration/components/git.go | 28 +++++++ pkg/integration/components/model.go | 84 ------------------- pkg/integration/components/shell.go | 11 +++ pkg/integration/components/test.go | 8 +- pkg/integration/components/test_driver.go | 14 +--- pkg/integration/components/test_test.go | 6 -- pkg/integration/components/view.go | 45 +++++++++- pkg/integration/tests/bisect/basic.go | 2 - .../tests/bisect/from_other_branch.go | 2 - pkg/integration/tests/branch/suggestions.go | 2 +- .../cherry_pick/cherry_pick_conflicts.go | 2 +- pkg/integration/tests/commit/commit.go | 10 ++- .../tests/commit/commit_multiline.go | 9 +- pkg/integration/tests/commit/new_branch.go | 10 +-- pkg/integration/tests/commit/revert.go | 2 - pkg/integration/tests/commit/staged.go | 10 ++- .../tests/commit/staged_without_hooks.go | 10 ++- pkg/integration/tests/commit/unstaged.go | 10 ++- .../tests/config/remote_named_star.go | 6 +- .../tests/custom_commands/basic.go | 3 +- .../tests/custom_commands/form_prompts.go | 10 ++- .../custom_commands/menu_from_command.go | 11 ++- .../menu_from_commands_output.go | 5 +- .../tests/custom_commands/multiple_prompts.go | 11 ++- .../tests/file/dir_with_untracked_file.go | 5 +- pkg/integration/tests/file/discard_changes.go | 4 +- .../tests/interactive_rebase/amend_merge.go | 18 ++-- pkg/integration/tests/misc/confirm_on_quit.go | 2 - pkg/integration/tests/stash/stash.go | 16 +++- .../stash/stash_including_untracked_files.go | 17 +++- pkg/integration/types/types.go | 1 - 32 files changed, 200 insertions(+), 178 deletions(-) create mode 100644 pkg/integration/components/git.go delete mode 100644 pkg/integration/components/model.go diff --git a/pkg/gui/gui_driver.go b/pkg/gui/gui_driver.go index 268d53f1d..cf1e3bbb4 100644 --- a/pkg/gui/gui_driver.go +++ b/pkg/gui/gui_driver.go @@ -49,10 +49,6 @@ func (self *GuiDriver) CurrentContext() types.Context { return self.gui.c.CurrentContext() } -func (self *GuiDriver) Model() *types.Model { - return self.gui.State.Model -} - func (self *GuiDriver) Fail(message string) { self.gui.g.Close() // need to give the gui time to close diff --git a/pkg/integration/components/git.go b/pkg/integration/components/git.go new file mode 100644 index 000000000..b9b3dcc46 --- /dev/null +++ b/pkg/integration/components/git.go @@ -0,0 +1,28 @@ +package components + +import ( + "fmt" + "strings" +) + +type Git struct { + *assertionHelper + shell *Shell +} + +func (self *Git) CurrentBranchName(expectedName string) *Git { + return self.assert("git rev-parse --abbrev-ref HEAD", expectedName) +} + +func (self *Git) assert(cmdStr string, expected string) *Git { + self.assertWithRetries(func() (bool, string) { + output, err := self.shell.runCommandWithOutput(cmdStr) + if err != nil { + return false, fmt.Sprintf("Unexpected error running command: `%s`. Error: %s", cmdStr, err.Error()) + } + actual := strings.TrimSpace(output) + return actual == expected, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expected, actual) + }) + + return self +} diff --git a/pkg/integration/components/model.go b/pkg/integration/components/model.go deleted file mode 100644 index 368c50852..000000000 --- a/pkg/integration/components/model.go +++ /dev/null @@ -1,84 +0,0 @@ -package components - -import ( - "fmt" - - integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" -) - -type Model struct { - *assertionHelper - gui integrationTypes.GuiDriver -} - -func (self *Model) WorkingTreeFileCount(expectedCount int) *Model { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().Files) - - return actualCount == expectedCount, fmt.Sprintf( - "Expected %d changed working tree files, but got %d", - expectedCount, actualCount, - ) - }) - - return self -} - -func (self *Model) CommitCount(expectedCount int) *Model { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().Commits) - - return actualCount == expectedCount, fmt.Sprintf( - "Expected %d commits present, but got %d", - expectedCount, actualCount, - ) - }) - - return self -} - -func (self *Model) StashCount(expectedCount int) *Model { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().StashEntries) - - return actualCount == expectedCount, fmt.Sprintf( - "Expected %d stash entries, but got %d", - expectedCount, actualCount, - ) - }) - - return self -} - -func (self *Model) AtLeastOneCommit() *Model { - self.assertWithRetries(func() (bool, string) { - actualCount := len(self.gui.Model().Commits) - - return actualCount > 0, "Expected at least one commit present" - }) - - return self -} - -func (self *Model) HeadCommitMessage(matcher *matcher) *Model { - self.assertWithRetries(func() (bool, string) { - return len(self.gui.Model().Commits) > 0, "Expected at least one commit to be present" - }) - - self.matchString(matcher, "Unexpected commit message.", - func() string { - return self.gui.Model().Commits[0].Name - }, - ) - - return self -} - -func (self *Model) CurrentBranchName(expectedViewName string) *Model { - self.assertWithRetries(func() (bool, string) { - actual := self.gui.CheckedOutRef().Name - return actual == expectedViewName, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expectedViewName, actual) - }) - - return self -} diff --git a/pkg/integration/components/shell.go b/pkg/integration/components/shell.go index 3fd63c8cc..f54d0fa5a 100644 --- a/pkg/integration/components/shell.go +++ b/pkg/integration/components/shell.go @@ -38,6 +38,17 @@ func (self *Shell) RunCommand(cmdStr string) *Shell { return self } +func (self *Shell) runCommandWithOutput(cmdStr string) (string, error) { + args := str.ToArgv(cmdStr) + cmd := secureexec.Command(args[0], args[1:]...) + cmd.Env = os.Environ() + cmd.Dir = self.dir + + output, err := cmd.CombinedOutput() + + return string(output), err +} + func (self *Shell) RunShellCommand(cmdStr string) *Shell { cmd := secureexec.Command("sh", "-c", cmdStr) cmd.Env = os.Environ() diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go index 0b36a12d9..9291cf329 100644 --- a/pkg/integration/components/test.go +++ b/pkg/integration/components/test.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/jesseduffield/lazygit/pkg/config" + "github.com/jesseduffield/lazygit/pkg/env" integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -89,9 +90,12 @@ func (self *IntegrationTest) SetupRepo(shell *Shell) { self.setupRepo(shell) } -// I want access to all contexts, the model, the ability to press a key, the ability to log, func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) { - shell := NewShell("/tmp/lazygit-test", func(errorMsg string) { gui.Fail(errorMsg) }) + // we pass the --pass arg to lazygit when running an integration test, and that + // ends up stored in the following env var + repoPath := env.GetGitWorkTreeEnv() + + shell := NewShell(repoPath, func(errorMsg string) { gui.Fail(errorMsg) }) keys := gui.Keys() testDriver := NewTestDriver(gui, shell, keys, KeyPressDelay()) diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index f2604d211..a314c9fd3 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -8,7 +8,6 @@ import ( "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/types" integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" - "github.com/samber/lo" ) type TestDriver struct { @@ -220,9 +219,9 @@ func (self *TestDriver) Views() *Views { return &Views{t: self} } -// for making assertions on the lazygit model -func (self *TestDriver) Model() *Model { - return &Model{assertionHelper: self.assertionHelper, gui: self.gui} +// for making assertions through git itself +func (self *TestDriver) Git() *Git { + return &Git{assertionHelper: self.assertionHelper, shell: self.shell} } // for making assertions on the file system @@ -235,10 +234,3 @@ func (self *TestDriver) FileSystem() *FileSystem { func (self *TestDriver) Fail(message string) { self.assertionHelper.fail(message) } - -func (self *TestDriver) NotInPopup() { - self.assertWithRetries(func() (bool, string) { - viewName := self.gui.CurrentContext().GetView().Name() - return !lo.Contains([]string{"menu", "confirmation", "commitMessage"}, viewName), fmt.Sprintf("Unexpected popup view present: %s view", viewName) - }) -} diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index ccab35dc8..6c2f15b4b 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -30,10 +30,6 @@ func (self *fakeGuiDriver) CurrentContext() types.Context { return nil } -func (self *fakeGuiDriver) Model() *types.Model { - return &types.Model{Commits: []*models.Commit{}} -} - func (self *fakeGuiDriver) Fail(message string) { self.failureMessage = message } @@ -66,7 +62,6 @@ func TestAssertionFailure(t *testing.T) { Run: func(t *TestDriver, keys config.KeybindingConfig) { t.press("a") t.press("b") - t.Model().CommitCount(2) }, }) driver := &fakeGuiDriver{} @@ -93,7 +88,6 @@ func TestSuccess(t *testing.T) { Run: func(t *TestDriver, keys config.KeybindingConfig) { t.press("a") t.press("b") - t.Model().CommitCount(0) }, }) driver := &fakeGuiDriver{} diff --git a/pkg/integration/components/view.go b/pkg/integration/components/view.go index 479c419cc..f809c3a4a 100644 --- a/pkg/integration/components/view.go +++ b/pkg/integration/components/view.go @@ -2,6 +2,7 @@ package components import ( "fmt" + "strings" "github.com/jesseduffield/gocui" ) @@ -28,6 +29,10 @@ func (self *View) Title(expected *matcher) *View { // This method is convenient when you have a list of commits but you only want to // assert on the first couple of commits. func (self *View) TopLines(matchers ...*matcher) *View { + if len(matchers) < 1 { + self.t.fail("TopLines method requires at least one matcher. If you are trying to assert that there are no lines, use .IsEmpty()") + } + self.t.assertWithRetries(func() (bool, string) { lines := self.getView().BufferLines() return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines)) @@ -39,10 +44,7 @@ func (self *View) TopLines(matchers ...*matcher) *View { // 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. func (self *View) Lines(matchers ...*matcher) *View { - self.t.assertWithRetries(func() (bool, string) { - lines := self.getView().BufferLines() - return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines)) - }) + self.LineCount(len(matchers)) return self.assertLines(matchers...) } @@ -184,6 +186,41 @@ func (self *View) NavigateToListItem(matcher *matcher) *View { return self } +// returns true if the view is a list view and it contains no items +func (self *View) IsEmpty() *View { + self.t.assertWithRetries(func() (bool, string) { + actual := strings.TrimSpace(self.getView().Buffer()) + return actual == "", fmt.Sprintf("%s: Unexpected content in view: expected no content. Content: %s", self.context, actual) + }) + + return self +} + +func (self *View) LineCount(expectedCount int) *View { + if expectedCount == 0 { + return self.IsEmpty() + } + + self.t.assertWithRetries(func() (bool, string) { + lines := self.getView().BufferLines() + return len(lines) == expectedCount, fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", expectedCount, len(lines)) + }) + + self.t.assertWithRetries(func() (bool, string) { + lines := self.getView().BufferLines() + + // if the view has a single blank line (often the case) we want to treat that as having no lines + if len(lines) == 1 && expectedCount == 1 { + actual := strings.TrimSpace(self.getView().Buffer()) + return actual == "", fmt.Sprintf("unexpected number of lines in view. Expected %d, got 0", expectedCount) + } + + return len(lines) == expectedCount, fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", expectedCount, len(lines)) + }) + + return self +} + // for when you want to make some assertion unrelated to the current view // without breaking the method chain func (self *View) Tap(f func()) *View { diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index 8294f61a4..5092f2f0a 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -29,8 +29,6 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() } - t.Model().AtLeastOneCommit() - t.Views().Commits(). Focus(). SelectedLine(Contains("commit 10")). diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 13e7e8055..7c2307bd6 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -21,8 +21,6 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Information().Content(Contains("bisecting")) - t.Model().AtLeastOneCommit() - t.Views().Commits(). Focus(). TopLines( diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index 65c64fa6d..0671578ed 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -34,6 +34,6 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ SelectFirstSuggestion(). Confirm() - t.Model().CurrentBranchName("branch-to-checkout") + t.Git().CurrentBranchName("branch-to-checkout") }, }) diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index 5eef30b50..c41de78b3 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -70,7 +70,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("all merge conflicts resolved. Continue?")). Confirm() - t.Model().WorkingTreeFileCount(0) + t.Views().Files().IsEmpty() t.Views().Commits(). Focus(). diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index 5950545e7..dc0615c87 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -15,7 +15,8 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("myfile2", "myfile2 content") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(0) + t.Views().Commits(). + IsEmpty() t.Views().Files(). IsFocused(). @@ -28,8 +29,9 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - t.Model(). - CommitCount(1). - HeadCommitMessage(Equals(commitMessage)) + t.Views().Commits(). + Lines( + Contains(commitMessage), + ) }, }) diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index 11876e09a..1a5175146 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -14,7 +14,8 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ shell.CreateFile("myfile", "myfile content") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(0) + t.Views().Commits(). + IsEmpty() t.Views().Files(). IsFocused(). @@ -23,8 +24,10 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectCommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() - t.Model().CommitCount(1) - t.Model().HeadCommitMessage(Equals("first line")) + t.Views().Commits(). + Lines( + Contains("first line"), + ) t.Views().Commits().Focus() t.Views().Main().Content(MatchesRegexp("first line\n\\s*\n\\s*third line")) diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index 6f528ff4c..16ae79b35 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -17,22 +17,20 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ EmptyCommit("commit 3") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(3) - t.Views().Commits(). Focus(). - SelectNextItem(). Lines( - Contains("commit 3"), - Contains("commit 2").IsSelected(), + Contains("commit 3").IsSelected(), + Contains("commit 2"), Contains("commit 1"), ). + SelectNextItem(). Press(keys.Universal.New). Tap(func() { branchName := "my-branch-name" t.ExpectPrompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() - t.Model().CurrentBranchName(branchName) + t.Git().CurrentBranchName(branchName) }). Lines( Contains("commit 2"), diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index bee657380..0f9c3fb9e 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -16,8 +16,6 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ shell.Commit("first commit") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(1) - t.Views().Commits(). Focus(). Lines( diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index d0698192a..d5c5dc84e 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -16,7 +16,8 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile2", "myfile2 content") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(0) + t.Views().Commits(). + IsEmpty() t.Views().Files(). IsFocused(). @@ -47,8 +48,11 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ commitMessage := "my commit message" t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - t.Model().CommitCount(1) - t.Model().HeadCommitMessage(Equals(commitMessage)) + t.Views().Commits(). + Lines( + Contains(commitMessage), + ) + t.Views().StagingSecondary().IsFocused() // 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 8a6b0d3d0..32cd8df06 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -16,7 +16,8 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile2", "myfile2 content") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(0) + t.Views().Commits(). + IsEmpty() // stage the file t.Views().Files(). @@ -47,8 +48,11 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ commitMessage := ": my commit message" t.ExpectCommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() - t.Model().CommitCount(1) - t.Model().HeadCommitMessage(Equals("WIP" + commitMessage)) + t.Views().Commits(). + Lines( + Contains("WIP" + commitMessage), + ) + t.Views().StagingSecondary().IsFocused() // 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 3e0d68617..a3792e1b7 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -18,7 +18,8 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ CreateFile("myfile2", "myfile2 content") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(0) + t.Views().Commits(). + IsEmpty() t.Views().Files(). IsFocused(). @@ -41,8 +42,11 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ commitMessage := "my commit message" t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() - t.Model().CommitCount(1) - t.Model().HeadCommitMessage(Equals(commitMessage)) + t.Views().Commits(). + Lines( + Contains(commitMessage), + ) + t.Views().Staging().IsFocused() // TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed) diff --git a/pkg/integration/tests/config/remote_named_star.go b/pkg/integration/tests/config/remote_named_star.go index 0306427ca..735389667 100644 --- a/pkg/integration/tests/config/remote_named_star.go +++ b/pkg/integration/tests/config/remote_named_star.go @@ -17,6 +17,10 @@ var RemoteNamedStar = NewIntegrationTest(NewIntegrationTestArgs{ SetupConfig: func(cfg *config.AppConfig) {}, Run: func(t *TestDriver, keys config.KeybindingConfig) { // here we're just asserting that we haven't panicked upon starting lazygit - t.Model().AtLeastOneCommit() + t.Views().Commits(). + Lines( + Anything(), + Anything(), + ) }, }) diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go index a73fab5a9..ce500b9a6 100644 --- a/pkg/integration/tests/custom_commands/basic.go +++ b/pkg/integration/tests/custom_commands/basic.go @@ -22,9 +22,8 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ } }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().WorkingTreeFileCount(0) - t.Views().Files(). + IsEmpty(). IsFocused(). Press("a"). Lines( diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index b35455368..c843232ee 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -56,9 +56,8 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ } }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().WorkingTreeFileCount(0) - t.Views().Files(). + IsEmpty(). IsFocused(). Press("a") @@ -71,8 +70,11 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - t.Model().WorkingTreeFileCount(1) - t.Views().Files().SelectedLine(Contains("my file")) + t.Views().Files(). + Lines( + Contains("my file").IsSelected(), + ) + t.Views().Main().Content(Contains(`"BAR"`)) }, }) diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index 580022521..71a6a5c15 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -43,7 +43,9 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ } }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().WorkingTreeFileCount(0) + t.Views().Files(). + IsEmpty() + t.Views().Branches(). Focus(). Press("a") @@ -52,9 +54,12 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectPrompt().Title(Equals("Description")).Type(" my branch").Confirm() - t.Model().WorkingTreeFileCount(1) + t.Views().Files(). + Focus(). + Lines( + Contains("output.txt").IsSelected(), + ) - t.Views().Files().Focus().SelectedLine(Contains("output.txt")) t.Views().Main().Content(Contains("bar Branch: #feature/foo my branch feature/foo")) }, }) 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 a9a899341..b4b649efd 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -42,8 +42,7 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ } }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CurrentBranchName("feature/bar") - t.Model().WorkingTreeFileCount(0) + t.Git().CurrentBranchName("feature/bar") t.Views().Branches(). Focus(). @@ -56,6 +55,6 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectMenu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() - t.Model().CurrentBranchName("master") + t.Git().CurrentBranchName("master") }, }) diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index fa69169aa..519160b88 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -54,9 +54,8 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ } }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().WorkingTreeFileCount(0) - t.Views().Files(). + IsEmpty(). IsFocused(). Press("a") @@ -69,8 +68,12 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() - t.Model().WorkingTreeFileCount(1) - t.Views().Files().SelectedLine(Contains("myfile")) + t.Views().Files(). + Focus(). + Lines( + Contains("myfile").IsSelected(), + ) + t.Views().Main().Content(Contains("BAR")) }, }) diff --git a/pkg/integration/tests/file/dir_with_untracked_file.go b/pkg/integration/tests/file/dir_with_untracked_file.go index e94d237d9..39da6e157 100644 --- a/pkg/integration/tests/file/dir_with_untracked_file.go +++ b/pkg/integration/tests/file/dir_with_untracked_file.go @@ -22,7 +22,10 @@ var DirWithUntrackedFile = NewIntegrationTest(NewIntegrationTestArgs{ shell.UpdateFile("dir/file", "baz") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(1) + t.Views().Commits(). + Lines( + Contains("first commit"), + ) t.Views().Main(). Content(DoesNotContain("error: Could not access")). diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index ab08ff9b9..e47695742 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -72,8 +72,6 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(3) - type statusFile struct { status string label string @@ -121,6 +119,6 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "??", label: "new.txt", menuTitle: "new.txt"}, }) - t.Model().WorkingTreeFileCount(0) + t.Views().Files().IsEmpty() }, }) diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 1f09af0de..7301f1806 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -28,10 +28,14 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ CreateFileAndAdd(postMergeFilename, postMergeFileContent) }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(3) - mergeCommitMessage := "Merge branch 'feature-branch' into development-branch" - t.Model().HeadCommitMessage(Contains(mergeCommitMessage)) + + t.Views().Commits(). + Lines( + Contains(mergeCommitMessage), + Contains("new feature commit"), + Contains("initial commit"), + ) t.Views().Commits(). Focus(). @@ -43,8 +47,12 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ Confirm() // assuring we haven't added a brand new commit - t.Model().CommitCount(3) - t.Model().HeadCommitMessage(Contains(mergeCommitMessage)) + t.Views().Commits(). + Lines( + Contains(mergeCommitMessage), + Contains("new feature commit"), + Contains("initial commit"), + ) // assuring the post-merge file shows up in the merge commit. t.Views().Main(). diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index 109ece2c9..b4124c4fc 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -14,8 +14,6 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ }, SetupRepo: func(shell *Shell) {}, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().CommitCount(0) - t.Views().Files(). IsFocused(). Press(keys.Universal.Quit) diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index 4265e0c23..c627faaf8 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -16,17 +16,25 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ shell.GitAddAll() }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().StashCount(0) - t.Model().WorkingTreeFileCount(1) + t.Views().Stash(). + IsEmpty() t.Views().Files(). + Lines( + Contains("file"), + ). Press(keys.Files.ViewStashOptions) t.ExpectMenu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() t.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - t.Model().StashCount(1) - t.Model().WorkingTreeFileCount(0) + t.Views().Stash(). + Lines( + Contains("my stashed file"), + ) + + t.Views().Files(). + IsEmpty() }, }) diff --git a/pkg/integration/tests/stash/stash_including_untracked_files.go b/pkg/integration/tests/stash/stash_including_untracked_files.go index d46d7fb1d..756f7948e 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -17,17 +17,26 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ shell.GitAdd("file_1") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Model().StashCount(0) - t.Model().WorkingTreeFileCount(2) + t.Views().Stash(). + IsEmpty() t.Views().Files(). + Lines( + Contains("file_1"), + Contains("file_2"), + ). Press(keys.Files.ViewStashOptions) t.ExpectMenu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() t.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() - t.Model().StashCount(1) - t.Model().WorkingTreeFileCount(0) + t.Views().Stash(). + Lines( + Contains("my stashed file"), + ) + + t.Views().Files(). + IsEmpty() }, }) diff --git a/pkg/integration/types/types.go b/pkg/integration/types/types.go index 4bc8569f7..5326054d2 100644 --- a/pkg/integration/types/types.go +++ b/pkg/integration/types/types.go @@ -20,7 +20,6 @@ type GuiDriver interface { PressKey(string) Keys() config.KeybindingConfig CurrentContext() types.Context - Model() *types.Model Fail(message string) // These two log methods are for the sake of debugging while testing. There's no need to actually // commit any logging. From 06c878c05116a3488ff9bd8fb9927235aba3d53e Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 10:23:54 +1100 Subject: [PATCH 13/20] minor changes --- pkg/integration/components/views.go | 40 +++++++++++++-------------- pkg/integration/tests/branch/reset.go | 7 +++-- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/pkg/integration/components/views.go b/pkg/integration/components/views.go index 4a95e5e0f..4d4348873 100644 --- a/pkg/integration/components/views.go +++ b/pkg/integration/components/views.go @@ -36,7 +36,7 @@ func (self *Views) Secondary() *View { } } -func (self *Views) ByName(viewName string) *View { +func (self *Views) byName(viewName string) *View { return &View{ context: fmt.Sprintf("%s view", viewName), getView: func() *gocui.View { return self.t.gui.View(viewName) }, @@ -45,77 +45,77 @@ func (self *Views) ByName(viewName string) *View { } func (self *Views) Commits() *View { - return self.ByName("commits") + return self.byName("commits") } func (self *Views) Files() *View { - return self.ByName("files") + return self.byName("files") } func (self *Views) Status() *View { - return self.ByName("status") + return self.byName("status") } func (self *Views) Submodules() *View { - return self.ByName("submodules") + return self.byName("submodules") } func (self *Views) Information() *View { - return self.ByName("information") + return self.byName("information") } func (self *Views) Branches() *View { - return self.ByName("localBranches") + return self.byName("localBranches") } func (self *Views) RemoteBranches() *View { - return self.ByName("remoteBranches") + return self.byName("remoteBranches") } func (self *Views) Tags() *View { - return self.ByName("tags") + return self.byName("tags") } func (self *Views) ReflogCommits() *View { - return self.ByName("reflogCommits") + return self.byName("reflogCommits") } func (self *Views) SubCommits() *View { - return self.ByName("subCommits") + return self.byName("subCommits") } func (self *Views) CommitFiles() *View { - return self.ByName("commitFiles") + return self.byName("commitFiles") } func (self *Views) Stash() *View { - return self.ByName("stash") + return self.byName("stash") } func (self *Views) Staging() *View { - return self.ByName("staging") + return self.byName("staging") } func (self *Views) StagingSecondary() *View { - return self.ByName("stagingSecondary") + return self.byName("stagingSecondary") } func (self *Views) Menu() *View { - return self.ByName("menu") + return self.byName("menu") } func (self *Views) Confirmation() *View { - return self.ByName("confirmation") + return self.byName("confirmation") } func (self *Views) CommitMessage() *View { - return self.ByName("commitMessage") + return self.byName("commitMessage") } func (self *Views) Suggestions() *View { - return self.ByName("suggestions") + return self.byName("suggestions") } func (self *Views) MergeConflicts() *View { - return self.ByName("mergeConflicts") + return self.byName("mergeConflicts") } diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index 65a10e31b..94288c718 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -29,13 +29,16 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Branches(). Focus(). Lines( - Contains("current-branch"), + Contains("current-branch").IsSelected(), Contains("other-branch"), ). SelectNextItem(). Press(keys.Commits.ViewResetOptions) - t.ExpectMenu().Title(Contains("reset to other-branch")).Select(Contains("hard reset")).Confirm() + t.ExpectMenu(). + Title(Contains("reset to other-branch")). + Select(Contains("hard reset")). + Confirm() // assert that we now have the expected commits in the commit panel t.Views().Commits(). From 47de61b57c132926352fd17643aa9c93066680f9 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 10:23:59 +1100 Subject: [PATCH 14/20] update integration test readme --- pkg/integration/README.md | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/pkg/integration/README.md b/pkg/integration/README.md index 2da3b5f81..616e09e98 100644 --- a/pkg/integration/README.md +++ b/pkg/integration/README.md @@ -24,17 +24,13 @@ In the setup step, we prepare a repo with shell commands, for example, creating ### Run step -The run step has three arguments passed in: +The run step has two arguments passed in: -1. `shell` -2. `t` (the test driver) -4. `keys` - -`shell` we've already seen in the setup step. The reason it's passed into the run step is that we may want to emulate background events. For example, the user modifying a file outside of lazygit. +1. `t` (the test driver) +2. `keys` `t` is for driving the gui by pressing certain keys, selecting list items, etc. - -`assert` is for asserting on the state of the lazygit session. When you call a method on `assert`, the assert struct will wait for the assertion to hold true and then continue (failing the test after a timeout). For this reason, assertions have two purposes: one is to ensure the test fails as soon as something unexpected happens, but another is to allow lazygit to process a keypress before you follow up with more keypresses. If you input a bunch of keypresses too quickly lazygit might get confused. +`keys` is for use when getting the test to press a particular key e.g. `t.Views().Commits().Focus().PressKey(keys.Universal.Confirm)` ### Tips @@ -46,18 +42,7 @@ Try to do as much setup work as possible in your setup step. For example, if all 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. For example: - -```go -// asserts that a prompt opens with the title 'Enter a file name', and then types 'my file' and confirms -t.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' -t.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 -t.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure?")) -``` +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 From f495945b87f1081fca5a0e6105075d63a91b7e1b Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 10:29:32 +1100 Subject: [PATCH 15/20] fix bug --- pkg/integration/components/view.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/integration/components/view.go b/pkg/integration/components/view.go index f809c3a4a..6386ebf3f 100644 --- a/pkg/integration/components/view.go +++ b/pkg/integration/components/view.go @@ -212,7 +212,7 @@ func (self *View) LineCount(expectedCount int) *View { // if the view has a single blank line (often the case) we want to treat that as having no lines if len(lines) == 1 && expectedCount == 1 { actual := strings.TrimSpace(self.getView().Buffer()) - return actual == "", fmt.Sprintf("unexpected number of lines in view. Expected %d, got 0", expectedCount) + return actual != "", "unexpected number of lines in view. Expected 1, got 0" } return len(lines) == expectedCount, fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", expectedCount, len(lines)) From b4e98063521f96bf65281a8e4bcec21a577df826 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 10:32:36 +1100 Subject: [PATCH 16/20] fix test --- .../tests/branch/rebase_and_drop.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index dc1cfddea..5996eb1fb 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -18,20 +18,20 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ shell.EmptyCommit("to keep") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Views().Branches(). - Focus(). - Lines( - Contains("first-change-branch"), - Contains("second-change-branch"), - Contains("original-branch"), - ) - t.Views().Commits(). TopLines( - Contains("to keep").IsSelected(), + Contains("to keep"), Contains("to remove"), Contains("first change"), Contains("original"), + ) + + t.Views().Branches(). + Focus(). + Lines( + Contains("first-change-branch").IsSelected(), + Contains("second-change-branch"), + Contains("original-branch"), ). SelectNextItem(). Press(keys.Branches.RebaseBranch) From a3450dfdfc9ade90147eb6103d8c2ddb9d7c7b00 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 10:41:42 +1100 Subject: [PATCH 17/20] fix suggestions test --- pkg/integration/components/prompt_asserter.go | 14 ++++++-------- pkg/integration/components/test_driver.go | 7 ------- pkg/integration/tests/branch/suggestions.go | 3 +-- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/pkg/integration/components/prompt_asserter.go b/pkg/integration/components/prompt_asserter.go index 9fea5bdf2..12b19bcd4 100644 --- a/pkg/integration/components/prompt_asserter.go +++ b/pkg/integration/components/prompt_asserter.go @@ -65,20 +65,18 @@ func (self *PromptAsserter) SuggestionTopLines(matchers ...*matcher) *PromptAsse return self } -func (self *PromptAsserter) SelectFirstSuggestion() *PromptAsserter { +func (self *PromptAsserter) ConfirmFirstSuggestion() { self.t.press(self.t.keys.Universal.TogglePanel) self.t.Views().Suggestions(). IsFocused(). - SelectedLineIdx(0) - - return self + SelectedLineIdx(0). + PressEnter() } -func (self *PromptAsserter) SelectSuggestion(matcher *matcher) *PromptAsserter { +func (self *PromptAsserter) ConfirmSuggestion(matcher *matcher) { self.t.press(self.t.keys.Universal.TogglePanel) self.t.Views().Suggestions(). IsFocused(). - NavigateToListItem(matcher) - - return self + NavigateToListItem(matcher). + PressEnter() } diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index a314c9fd3..dc6fd421f 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -207,13 +207,6 @@ func (self *TestDriver) inCommitMessagePanel() { }) } -func (self *TestDriver) currentWindowName(expectedWindowName string) { - self.assertWithRetries(func() (bool, string) { - actual := self.gui.CurrentContext().GetView().Name() - return actual == expectedWindowName, fmt.Sprintf("Expected current window name to be '%s', but got '%s'", expectedWindowName, actual) - }) -} - // for making assertions on lazygit views func (self *TestDriver) Views() *Views { return &Views{t: self} diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index 0671578ed..bac0fe83b 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -31,8 +31,7 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ Title(Equals("Branch name:")). Type("branch-to"). SuggestionTopLines(Contains("branch-to-checkout")). - SelectFirstSuggestion(). - Confirm() + ConfirmFirstSuggestion() t.Git().CurrentBranchName("branch-to-checkout") }, From a27092a7ad24044e260124c390bd35fac59a3860 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 10:43:14 +1100 Subject: [PATCH 18/20] remove broken test --- pkg/integration/components/test_test.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index 6c2f15b4b..08823f525 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -56,20 +56,6 @@ func (self *fakeGuiDriver) View(viewName string) *gocui.View { return nil } -func TestAssertionFailure(t *testing.T) { - test := NewIntegrationTest(NewIntegrationTestArgs{ - Description: unitTestDescription, - Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.press("a") - t.press("b") - }, - }) - driver := &fakeGuiDriver{} - test.Run(driver) - assert.EqualValues(t, []string{"a", "b"}, driver.pressedKeys) - assert.Equal(t, "Expected 2 commits present, but got 0", driver.failureMessage) -} - func TestManualFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, From 7aa843c75a9d16472120c1e8869be4c1cfd843af Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 10:54:38 +1100 Subject: [PATCH 19/20] create actions struct --- pkg/integration/components/actions.go | 19 +++++++++++++++++++ pkg/integration/components/test_driver.go | 13 ++----------- .../tests/interactive_rebase/one.go | 2 +- 3 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 pkg/integration/components/actions.go diff --git a/pkg/integration/components/actions.go b/pkg/integration/components/actions.go new file mode 100644 index 000000000..8489a52f8 --- /dev/null +++ b/pkg/integration/components/actions.go @@ -0,0 +1,19 @@ +package components + +// for running common actions +type Actions struct { + t *TestDriver +} + +func (self *Actions) ContinueMerge() { + self.t.Views().current().Press(self.t.keys.Universal.CreateRebaseOptionsMenu) + + self.t.ExpectMenu(). + Title(Equals("Rebase Options")). + Select(Contains("continue")). + Confirm() +} + +func (self *Actions) ContinueRebase() { + self.ContinueMerge() +} diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index dc6fd421f..d4ca76662 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -42,17 +42,8 @@ func (self *TestDriver) typeContent(content string) { } } -func (self *TestDriver) ContinueMerge() { - self.Views().current().Press(self.keys.Universal.CreateRebaseOptionsMenu) - - self.ExpectMenu(). - Title(Equals("Rebase Options")). - Select(Contains("continue")). - Confirm() -} - -func (self *TestDriver) ContinueRebase() { - self.ContinueMerge() +func (self *TestDriver) Actions() *Actions { + return &Actions{t: self} } // for when you want to allow lazygit to process something before continuing diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go index fdfc2db52..d6d01239a 100644 --- a/pkg/integration/tests/interactive_rebase/one.go +++ b/pkg/integration/tests/interactive_rebase/one.go @@ -61,7 +61,7 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 01"), ). Tap(func() { - t.ContinueRebase() + t.Actions().ContinueRebase() }). Lines( Contains("commit 02"), From 9fef4447b67c499fe34d40bc5dadc5941ac39b7c Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 28 Dec 2022 11:00:22 +1100 Subject: [PATCH 20/20] move popup assertions into a struct --- pkg/integration/components/actions.go | 2 +- pkg/integration/components/popup.go | 70 +++++++++++++++++++ pkg/integration/components/test_driver.go | 70 ++----------------- pkg/integration/tests/bisect/basic.go | 6 +- .../tests/bisect/from_other_branch.go | 4 +- .../tests/branch/checkout_by_name.go | 4 +- pkg/integration/tests/branch/delete.go | 4 +- pkg/integration/tests/branch/rebase.go | 6 +- .../tests/branch/rebase_and_drop.go | 6 +- pkg/integration/tests/branch/reset.go | 2 +- pkg/integration/tests/branch/suggestions.go | 2 +- .../tests/cherry_pick/cherry_pick.go | 2 +- .../cherry_pick/cherry_pick_conflicts.go | 6 +- pkg/integration/tests/commit/commit.go | 2 +- .../tests/commit/commit_multiline.go | 2 +- pkg/integration/tests/commit/new_branch.go | 2 +- pkg/integration/tests/commit/revert.go | 2 +- pkg/integration/tests/commit/staged.go | 2 +- .../tests/commit/staged_without_hooks.go | 2 +- pkg/integration/tests/commit/unstaged.go | 2 +- .../tests/custom_commands/form_prompts.go | 6 +- .../custom_commands/menu_from_command.go | 4 +- .../menu_from_commands_output.go | 4 +- .../tests/custom_commands/multiple_prompts.go | 6 +- pkg/integration/tests/diff/diff.go | 4 +- .../tests/diff/diff_and_apply_patch.go | 6 +- pkg/integration/tests/diff/diff_commits.go | 4 +- pkg/integration/tests/file/discard_changes.go | 4 +- .../tests/interactive_rebase/amend_merge.go | 2 +- pkg/integration/tests/misc/confirm_on_quit.go | 2 +- pkg/integration/tests/stash/rename.go | 2 +- pkg/integration/tests/stash/stash.go | 4 +- .../stash/stash_including_untracked_files.go | 4 +- 33 files changed, 130 insertions(+), 120 deletions(-) create mode 100644 pkg/integration/components/popup.go diff --git a/pkg/integration/components/actions.go b/pkg/integration/components/actions.go index 8489a52f8..fb4114890 100644 --- a/pkg/integration/components/actions.go +++ b/pkg/integration/components/actions.go @@ -8,7 +8,7 @@ type Actions struct { func (self *Actions) ContinueMerge() { self.t.Views().current().Press(self.t.keys.Universal.CreateRebaseOptionsMenu) - self.t.ExpectMenu(). + self.t.ExpectPopup().Menu(). Title(Equals("Rebase Options")). Select(Contains("continue")). Confirm() diff --git a/pkg/integration/components/popup.go b/pkg/integration/components/popup.go new file mode 100644 index 000000000..7cd2b2ffc --- /dev/null +++ b/pkg/integration/components/popup.go @@ -0,0 +1,70 @@ +package components + +type Popup struct { + t *TestDriver +} + +func (self *Popup) Confirmation() *ConfirmationAsserter { + self.inConfirm() + + return &ConfirmationAsserter{t: self.t} +} + +func (self *Popup) inConfirm() { + self.t.assertWithRetries(func() (bool, string) { + currentView := self.t.gui.CurrentContext().GetView() + return currentView.Name() == "confirmation" && !currentView.Editable, "Expected confirmation popup to be focused" + }) +} + +func (self *Popup) Prompt() *PromptAsserter { + self.inPrompt() + + return &PromptAsserter{t: self.t} +} + +func (self *Popup) inPrompt() { + self.t.assertWithRetries(func() (bool, string) { + currentView := self.t.gui.CurrentContext().GetView() + return currentView.Name() == "confirmation" && currentView.Editable, "Expected prompt popup to be focused" + }) +} + +func (self *Popup) Alert() *AlertAsserter { + self.inAlert() + + return &AlertAsserter{t: self.t} +} + +func (self *Popup) inAlert() { + // basically the same thing as a confirmation popup with the current implementation + self.t.assertWithRetries(func() (bool, string) { + currentView := self.t.gui.CurrentContext().GetView() + return currentView.Name() == "confirmation" && !currentView.Editable, "Expected alert popup to be focused" + }) +} + +func (self *Popup) Menu() *MenuAsserter { + self.inMenu() + + return &MenuAsserter{t: self.t} +} + +func (self *Popup) inMenu() { + self.t.assertWithRetries(func() (bool, string) { + return self.t.gui.CurrentContext().GetView().Name() == "menu", "Expected popup menu to be focused" + }) +} + +func (self *Popup) CommitMessagePanel() *CommitMessagePanelAsserter { + self.inCommitMessagePanel() + + return &CommitMessagePanelAsserter{t: self.t} +} + +func (self *Popup) inCommitMessagePanel() { + self.t.assertWithRetries(func() (bool, string) { + currentView := self.t.gui.CurrentContext().GetView() + return currentView.Name() == "commitMessage", "Expected commit message panel to be focused" + }) +} diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index d4ca76662..5f2e15435 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -133,76 +133,16 @@ func (self *TestDriver) inListContext() { }) } -func (self *TestDriver) ExpectConfirmation() *ConfirmationAsserter { - self.inConfirm() - - return &ConfirmationAsserter{t: self} -} - -func (self *TestDriver) inConfirm() { - self.assertWithRetries(func() (bool, string) { - currentView := self.gui.CurrentContext().GetView() - return currentView.Name() == "confirmation" && !currentView.Editable, "Expected confirmation popup to be focused" - }) -} - -func (self *TestDriver) ExpectPrompt() *PromptAsserter { - self.inPrompt() - - return &PromptAsserter{t: self} -} - -func (self *TestDriver) inPrompt() { - self.assertWithRetries(func() (bool, string) { - currentView := self.gui.CurrentContext().GetView() - return currentView.Name() == "confirmation" && currentView.Editable, "Expected prompt popup to be focused" - }) -} - -func (self *TestDriver) ExpectAlert() *AlertAsserter { - self.inAlert() - - return &AlertAsserter{t: self} -} - -func (self *TestDriver) inAlert() { - // basically the same thing as a confirmation popup with the current implementation - self.assertWithRetries(func() (bool, string) { - currentView := self.gui.CurrentContext().GetView() - return currentView.Name() == "confirmation" && !currentView.Editable, "Expected alert popup to be focused" - }) -} - -func (self *TestDriver) ExpectMenu() *MenuAsserter { - self.inMenu() - - return &MenuAsserter{t: self} -} - -func (self *TestDriver) inMenu() { - self.assertWithRetries(func() (bool, string) { - return self.gui.CurrentContext().GetView().Name() == "menu", "Expected popup menu to be focused" - }) -} - -func (self *TestDriver) ExpectCommitMessagePanel() *CommitMessagePanelAsserter { - self.inCommitMessagePanel() - - return &CommitMessagePanelAsserter{t: self} -} - -func (self *TestDriver) inCommitMessagePanel() { - self.assertWithRetries(func() (bool, string) { - currentView := self.gui.CurrentContext().GetView() - return currentView.Name() == "commitMessage", "Expected commit message panel to be focused" - }) -} - // for making assertions on lazygit views func (self *TestDriver) Views() *Views { return &Views{t: self} } +// for interacting with popups +func (self *TestDriver) ExpectPopup() *Popup { + return &Popup{t: self} +} + // for making assertions through git itself func (self *TestDriver) Git() *Git { return &Git{assertionHelper: self.assertionHelper, shell: self.shell} diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index 5092f2f0a..ca06d5fa5 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -19,14 +19,14 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Commits(). Press(keys.Commits.ViewBisectOptions) - t.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as bad`)).Confirm() + t.ExpectPopup().Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as bad`)).Confirm() } markCommitAsGood := func() { t.Views().Commits(). Press(keys.Commits.ViewBisectOptions) - t.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() + t.ExpectPopup().Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() } t.Views().Commits(). @@ -49,7 +49,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ markCommitAsGood() // commit 5 is the culprit because we marked 4 as good and 5 as bad. - t.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() + t.ExpectPopup().Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 05.*Do you want to reset")).Confirm() }). IsFocused(). Content(Contains("commit 04")) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 7c2307bd6..ecac6ea3f 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -32,9 +32,9 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Commits.ViewBisectOptions). Tap(func() { - t.ExpectMenu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() + t.ExpectPopup().Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`mark .* as good`)).Confirm() - t.ExpectAlert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() + t.ExpectPopup().Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit 08.*Do you want to reset")).Confirm() t.Views().Information().Content(DoesNotContain("bisecting")) }). diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index c786f8970..070a3a433 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -27,9 +27,9 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Branches.CheckoutBranchByName). Tap(func() { - t.ExpectPrompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() + t.ExpectPopup().Prompt().Title(Equals("Branch name:")).Type("new-branch").Confirm() - t.ExpectAlert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() + t.ExpectPopup().Alert().Title(Equals("Branch not found")).Content(Equals("Branch not found. Create a new branch named new-branch?")).Confirm() }). Lines( MatchesRegexp(`\*.*new-branch`).IsSelected(), diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 520923cd6..7d93513dc 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -26,12 +26,12 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.Remove). Tap(func() { - t.ExpectAlert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() + t.ExpectPopup().Alert().Title(Equals("Error")).Content(Contains("You cannot delete the checked out branch!")).Confirm() }). SelectNextItem(). Press(keys.Universal.Remove). Tap(func() { - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Delete Branch")). Content(Contains("Are you sure you want to delete the branch 'branch-one'?")). Confirm() diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index 137bada27..e59aa8cb2 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -30,12 +30,12 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Branches.RebaseBranch) - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() @@ -51,7 +51,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Information().Content(Contains("rebasing")) - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 5996eb1fb..5f5341d66 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -36,14 +36,14 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Branches.RebaseBranch) - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Rebasing")). Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() t.Views().Information().Content(Contains("rebasing")) - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() @@ -78,7 +78,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). PressPrimaryAction() - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index 94288c718..0a46ad2a1 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -35,7 +35,7 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Commits.ViewResetOptions) - t.ExpectMenu(). + t.ExpectPopup().Menu(). Title(Contains("reset to other-branch")). Select(Contains("hard reset")). Confirm() diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index bac0fe83b..5b5b23403 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -27,7 +27,7 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ // we expect the first suggestion to be the branch we want because it most // closely matches what we typed in - t.ExpectPrompt(). + t.ExpectPopup().Prompt(). Title(Equals("Branch name:")). Type("branch-to"). SuggestionTopLines(Contains("branch-to-checkout")). diff --git a/pkg/integration/tests/cherry_pick/cherry_pick.go b/pkg/integration/tests/cherry_pick/cherry_pick.go index a9d7dd9c7..7aaaf36f1 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -60,7 +60,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Commits.PasteCommits). Tap(func() { - t.ExpectAlert(). + t.ExpectPopup().Alert(). Title(Equals("Cherry-Pick")). Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). Confirm() diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index c41de78b3..df9988c2a 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -47,9 +47,9 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Commits.PasteCommits) - t.ExpectAlert().Title(Equals("Cherry-Pick")).Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).Confirm() + t.ExpectPopup().Alert().Title(Equals("Cherry-Pick")).Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).Confirm() - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() @@ -65,7 +65,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). PressPrimaryAction() - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index dc0615c87..6ed75a797 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -27,7 +27,7 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ commitMessage := "my commit message" - t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() + t.ExpectPopup().CommitMessagePanel().Type(commitMessage).Confirm() t.Views().Commits(). Lines( diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index 1a5175146..4967ffb77 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -22,7 +22,7 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ PressPrimaryAction(). Press(keys.Files.CommitChanges) - t.ExpectCommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() + t.ExpectPopup().CommitMessagePanel().Type("first line").AddNewline().AddNewline().Type("third line").Confirm() t.Views().Commits(). Lines( diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index 16ae79b35..d3cd58f23 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -28,7 +28,7 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Universal.New). Tap(func() { branchName := "my-branch-name" - t.ExpectPrompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() + t.ExpectPopup().Prompt().Title(Contains("New Branch Name")).Type(branchName).Confirm() t.Git().CurrentBranchName(branchName) }). diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index 0f9c3fb9e..3b55aa65d 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -23,7 +23,7 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Commits.RevertCommit). Tap(func() { - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Revert commit")). Content(MatchesRegexp(`Are you sure you want to revert \w+?`)). Confirm() diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index d5c5dc84e..09bcf2815 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -46,7 +46,7 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Files.CommitChanges) commitMessage := "my commit message" - t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() + t.ExpectPopup().CommitMessagePanel().Type(commitMessage).Confirm() t.Views().Commits(). Lines( diff --git a/pkg/integration/tests/commit/staged_without_hooks.go b/pkg/integration/tests/commit/staged_without_hooks.go index 32cd8df06..620f712f9 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -46,7 +46,7 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Files.CommitChangesWithoutHook) commitMessage := ": my commit message" - t.ExpectCommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() + t.ExpectPopup().CommitMessagePanel().InitialText(Contains("WIP")).Type(commitMessage).Confirm() t.Views().Commits(). Lines( diff --git a/pkg/integration/tests/commit/unstaged.go b/pkg/integration/tests/commit/unstaged.go index a3792e1b7..c0e26b281 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -40,7 +40,7 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Files.CommitChanges) commitMessage := "my commit message" - t.ExpectCommitMessagePanel().Type(commitMessage).Confirm() + t.ExpectPopup().CommitMessagePanel().Type(commitMessage).Confirm() t.Views().Commits(). Lines( diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index c843232ee..dcb41c83e 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -61,11 +61,11 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). Press("a") - t.ExpectPrompt().Title(Equals("Enter a file name")).Type("my file").Confirm() + t.ExpectPopup().Prompt().Title(Equals("Enter a file name")).Type("my file").Confirm() - t.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index 71a6a5c15..db856c807 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -50,9 +50,9 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ Focus(). Press("a") - t.ExpectMenu().Title(Equals("Choose commit message")).Select(Contains("bar")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Choose commit message")).Select(Contains("bar")).Confirm() - t.ExpectPrompt().Title(Equals("Description")).Type(" my branch").Confirm() + t.ExpectPopup().Prompt().Title(Equals("Description")).Type(" my branch").Confirm() t.Views().Files(). Focus(). 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 b4b649efd..123e27695 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -48,12 +48,12 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ Focus(). Press("a") - t.ExpectPrompt(). + t.ExpectPopup().Prompt(). Title(Equals("Which git command do you want to run?")). InitialText(Equals("branch")). Confirm() - t.ExpectMenu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Branch:")).Select(Equals("master")).Confirm() t.Git().CurrentBranchName("master") }, diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index 519160b88..b1592d03b 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -59,11 +59,11 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). Press("a") - t.ExpectPrompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() + t.ExpectPopup().Prompt().Title(Equals("Enter a file name")).Type("myfile").Confirm() - t.ExpectMenu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Choose file content")).Select(Contains("bar")).Confirm() - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Are you sure?")). Content(Equals("Are you REALLY sure you want to make this file? Up to you buddy.")). Confirm() diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index 7d66cc49d..8730fd881 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -30,7 +30,7 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.DiffingMenu) - t.ExpectMenu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() + t.ExpectPopup().Menu().Title(Equals("Diffing")).Select(Contains(`diff branch-a`)).Confirm() t.Views().Branches(). IsFocused(). @@ -66,7 +66,7 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). Press(keys.Universal.DiffingMenu) - t.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() t.Views().Information().Content(Contains("showing output for: git diff branch-a branch-b -R")) t.Views().Main().Content(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 94cd29a6c..8988b0493 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -30,7 +30,7 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.DiffingMenu) - t.ExpectMenu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Diffing")).Select(Equals("diff branch-a")).Confirm() t.Views().Information().Content(Contains("showing output for: git diff branch-a branch-a")) @@ -60,14 +60,14 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ PressPrimaryAction(). // add the file to the patch Press(keys.Universal.DiffingMenu). Tap(func() { - t.ExpectMenu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Diffing")).Select(Contains("exit diff mode")).Confirm() t.Views().Information().Content(DoesNotContain("building patch")) }). Press(keys.Universal.CreatePatchOptionsMenu) // adding the regex '$' here to distinguish the menu item from the 'apply patch in reverse' item - t.ExpectMenu().Title(Equals("Patch Options")).Select(MatchesRegexp("apply patch$")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Patch Options")).Select(MatchesRegexp("apply patch$")).Confirm() t.Views().Files(). Focus(). diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index 68d4e99fd..6de643272 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -28,7 +28,7 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.DiffingMenu). Tap(func() { - t.ExpectMenu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() + t.ExpectPopup().Menu().Title(Equals("Diffing")).Select(MatchesRegexp(`diff \w+`)).Confirm() t.Views().Information().Content(Contains("showing output for: git diff")) }). @@ -40,7 +40,7 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ }). Press(keys.Universal.DiffingMenu). Tap(func() { - t.ExpectMenu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Diffing")).Select(Contains("reverse diff direction")).Confirm() t.Views().Main().Content(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 e47695742..f3fc11a01 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -85,7 +85,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ SelectedLine(Contains(file.status + " " + file.label)). Press(keys.Universal.Remove) - t.ExpectMenu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() + t.ExpectPopup().Menu().Title(Equals(file.menuTitle)).Select(Contains("discard all changes")).Confirm() } } @@ -99,7 +99,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"}, }) - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Cancel() diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index 7301f1806..7e5e64746 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -41,7 +41,7 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ Focus(). Press(keys.Commits.AmendToCommit) - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("Amend Commit")). Content(Contains("Are you sure you want to amend this commit with your staged files?")). Confirm() diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index b4124c4fc..18b27a108 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -18,7 +18,7 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). Press(keys.Universal.Quit) - t.ExpectConfirmation(). + t.ExpectPopup().Confirmation(). Title(Equals("")). Content(Contains("Are you sure you want to quit?")). Confirm() diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index fded5041c..0b47bcef3 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -28,7 +28,7 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). Press(keys.Stash.RenameStash). Tap(func() { - t.ExpectPrompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() + t.ExpectPopup().Prompt().Title(Equals("Rename stash: stash@{1}")).Type(" baz").Confirm() }). SelectedLine(Equals("On master: foo baz")) }, diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index c627faaf8..f88aac2d0 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -25,9 +25,9 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Files.ViewStashOptions) - t.ExpectMenu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Stash options")).Select(MatchesRegexp("stash all changes$")).Confirm() - t.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() + t.ExpectPopup().Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() t.Views().Stash(). Lines( diff --git a/pkg/integration/tests/stash/stash_including_untracked_files.go b/pkg/integration/tests/stash/stash_including_untracked_files.go index 756f7948e..770c87b9c 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -27,9 +27,9 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Files.ViewStashOptions) - t.ExpectMenu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() + t.ExpectPopup().Menu().Title(Equals("Stash options")).Select(Contains("stash all changes including untracked files")).Confirm() - t.ExpectPrompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() + t.ExpectPopup().Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm() t.Views().Stash(). Lines(