From a881fb7ee0f5c0e231376b2de1ea2198dfc3d3b7 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 8 Aug 2026 15:09:21 +0200 Subject: [PATCH] Add a test for paging up and down in a list We are about to make list panels scroll their selection into view automatically. Page up and down are one of the few places that manage the scroll position themselves, keeping the selection at the edge of the viewport rather than in its middle, and nothing covers that today. Asserting on it needs an exact scroll position assertion; only OriginYAtLeast existed so far. Co-Authored-By: Claude Opus 5 (1M context) --- pkg/integration/components/view_driver.go | 11 +++++ pkg/integration/tests/test_list.go | 1 + pkg/integration/tests/ui/page_up_and_down.go | 47 ++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 pkg/integration/tests/ui/page_up_and_down.go diff --git a/pkg/integration/components/view_driver.go b/pkg/integration/components/view_driver.go index 937c19b7b..bc0969f24 100644 --- a/pkg/integration/components/view_driver.go +++ b/pkg/integration/components/view_driver.go @@ -355,6 +355,17 @@ func (self *ViewDriver) SelectedLineIdxAtLeast(expected int) *ViewDriver { return self } +// asserts on the scroll position of the view, i.e. the index of the line that +// is shown at the top of the view. +func (self *ViewDriver) OriginY(expected int) *ViewDriver { + self.t.assertWithRetries(func() (bool, string) { + actual := self.getView().OriginY() + return expected == actual, fmt.Sprintf("%s: Expected origin Y to be %d, got %d", self.context, expected, actual) + }) + + return self +} + func (self *ViewDriver) OriginYAtLeast(expected int) *ViewDriver { self.t.assertEventually(func() (bool, string) { var actual int diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 15ef6f8c7..2d88de8e9 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -505,6 +505,7 @@ var tests = []*components.IntegrationTest{ ui.KeybindingSuggestionsWhenSwitchingRepos, ui.ModeSpecificKeybindingSuggestions, ui.OpenLinkFailure, + ui.PageUpAndDown, ui.PromoteTabToSidePanel, ui.RangeSelect, ui.RangeSelectWithAutoscroll, diff --git a/pkg/integration/tests/ui/page_up_and_down.go b/pkg/integration/tests/ui/page_up_and_down.go new file mode 100644 index 000000000..603edfd92 --- /dev/null +++ b/pkg/integration/tests/ui/page_up_and_down.go @@ -0,0 +1,47 @@ +package ui + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +const ( + // The height of the commits panel in this test's window, in lines. + commitsPanelHeight = 5 + // Paging keeps one line of overlap between the old and the new page. + pageDelta = commitsPanelHeight - 1 +) + +var PageUpAndDown = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Paging down and up keeps the selection at the edge of the viewport", + ExtraCmdArgs: []string{}, + Skip: false, + Width: 120, + Height: 30, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateNCommits(40) + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + SelectedLineIdx(0). + OriginY(0). + Press(keys.Universal.NextPage). + // The selection moves to the bottom of the viewport; nothing scrolls yet + SelectedLineIdx(commitsPanelHeight - 1). + OriginY(0). + Press(keys.Universal.NextPage). + // Now the view scrolls by a page, and the selection stays at the bottom + SelectedLineIdx(commitsPanelHeight - 1 + pageDelta). + OriginY(pageDelta). + Press(keys.Universal.PrevPage). + // The selection moves to the top of the viewport; nothing scrolls + SelectedLineIdx(pageDelta). + OriginY(pageDelta). + Press(keys.Universal.PrevPage). + // And back a page, with the selection staying at the top + SelectedLineIdx(0). + OriginY(0) + }, +})