Pad/internal/test/e2e/browser_files_test.go

214 lines
6.3 KiB
Go

package e2e_test
import (
"fmt"
"testing"
"time"
"pad/internal/browser"
"pad/internal/editor"
"pad/internal/test/e2e"
"pad/internal/ui"
)
// TestBrowserFilesVisible verifies that files from the mock filesystem
// are rendered in the browser page. This test fails when the root directory
// "/" is not registered in the mock filesystem, causing ReadDir("/") to fail
// and TotalEntries to remain 0.
func TestBrowserFilesVisible(t *testing.T) {
// Create harness with defaults (780x1688 @ 2x scale)
h := e2e.NewHarnessWithDefaults()
defer h.Cleanup()
// Wait for initial frame(s) — this includes the BuildIndexTask result
_, err := h.WaitForFrameCount(1, 5*time.Second)
if err != nil {
t.Fatalf("timeout waiting for initial frames: %v", err)
}
// Set VisibleCount based on viewport
state := h.State()
state.Browser.VisibleCount = computeVisibleCount(state.PixelHeight, state.Scale())
// Switch to browser page
editor.GoToBrowser(nil)
// Trigger a frame
h.SendConfig(780, 1688)
// Wait for new frames after navigation
time.Sleep(200 * time.Millisecond)
frames := h.GetFrames()
if len(frames) == 0 {
t.Fatal("no frames captured")
}
lastFrame := frames[len(frames)-1]
// Debug: print what we got
t.Logf("Frame has %d elements", len(lastFrame))
for i, elem := range lastFrame {
t.Logf(" [%d] %T: region=%+v", i, elem, elem.Region())
}
// Find the ListView in the frame
var listView *ui.ListView
for _, elem := range lastFrame {
if lv, ok := elem.(ui.ListView); ok {
listView = &lv
break
}
}
if listView == nil {
t.Fatal("expected ListView element in browser frame, not found")
}
// The mock filesystem has 5 root-level files and 6 directories = 11 entries
if len(listView.Items) == 0 {
t.Errorf("browser ListView has 0 items — files from mock filesystem not showing up")
t.Logf("BrowserState: TotalEntries=%d, VisibleCount=%d, ScrollOffset=%.1f",
state.Browser.TotalEntries,
state.Browser.VisibleCount,
state.Browser.ScrollOffset)
}
// Verify some known files are present
expectedFiles := []string{"README.md", "config.yaml", "notes.txt"}
for _, expected := range expectedFiles {
found := false
for _, item := range listView.Items {
if item.Text == expected {
found = true
break
}
}
if !found {
t.Errorf("expected file %q in browser list, not found", expected)
}
}
}
// computeVisibleCount calculates how many entries fit on screen.
// Each row is 48 Dp; we subtract header, search bar, and margins.
func computeVisibleCount(pixelHeight int, scale float32) int {
screenDp := ui.ToDp(ui.Px(pixelHeight), scale)
// Subtract: top margin (10), header (24), gap (5), search bar (36), gap (5), bottom margin (10)
listAreaHeight := screenDp - ui.Dp(10+24+5+36+5+10)
rowHeight := ui.Dp(48)
return int(listAreaHeight / rowHeight)
}
// TestBrowserLayoutWithVisibleCount tests the browser layout function directly
// with a properly configured VisibleCount to verify the rendering pipeline works.
func TestBrowserLayoutWithVisibleCount(t *testing.T) {
// Create a browser state with known entries
state := browser.NewBrowserState()
state.CurrentPath = "/"
state.VisibleCount = 30
// Populate with mock entries
entries := []browser.Entry{
browser.NewEntry("/README.md", "README.md", 2048, time.Now(), false),
browser.NewEntry("/config.yaml", "config.yaml", 512, time.Now(), false),
browser.NewEntry("/Documents", "Documents", 0, time.Now(), true),
}
state.TotalEntries = len(entries)
state.SortIndex = &browser.DirectoryIndex{
Path: "/",
EntryCount: len(entries),
Entries: entries,
SortOrders: map[string][]int{
"name_asc": {0, 1, 2},
},
}
state.SortMode = browser.SortModeNameAsc
// Load pages
browser.LoadInitialPages(state)
// Compute layout
screenW := ui.Dp(390)
screenH := ui.Dp(844)
// Pass a dummy sort handler since we're only testing layout
elements := browser.BrowserLayout(screenW, screenH, state, func(any) {}, func(any) {})
// Find the ListView
var listView *ui.ListView
for _, elem := range elements {
if lv, ok := elem.(ui.ListView); ok {
listView = &lv
break
}
}
if listView == nil {
t.Fatal("expected ListView in browser layout")
}
if len(listView.Items) == 0 {
t.Fatal("ListView has 0 items despite VisibleCount=30 and 3 entries")
}
// Should show all 3 entries
if len(listView.Items) != 3 {
t.Errorf("expected 3 items, got %d", len(listView.Items))
}
}
// TestBrowserVisibleCountDefaultIsZero confirms that VisibleCount defaults to 0.
func TestBrowserVisibleCountDefaultIsZero(t *testing.T) {
state := browser.NewBrowserState()
if state.VisibleCount != 0 {
t.Errorf("expected VisibleCount to default to 0, got %d", state.VisibleCount)
}
// With VisibleCount=0, computeVisibleEntries returns nothing
state.TotalEntries = 10
state.SortIndex = &browser.DirectoryIndex{
Path: "/",
EntryCount: 10,
Entries: make([]browser.Entry, 10),
SortOrders: map[string][]int{
"name_asc": {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
},
}
for i := range state.SortIndex.Entries {
state.SortIndex.Entries[i] = browser.NewEntry(
fmt.Sprintf("/file%d.txt", i),
fmt.Sprintf("file%d.txt", i),
100,
time.Now(),
false,
)
}
state.SortMode = browser.SortModeNameAsc
browser.LoadInitialPages(state)
// Compute visible entries with VisibleCount=0
visibleEntries := browser.ComputeVisibleEntriesForTest(state)
if len(visibleEntries) != 0 {
t.Errorf("expected 0 visible entries with VisibleCount=0, got %d", len(visibleEntries))
}
// Now set VisibleCount and verify entries appear
state.VisibleCount = 30
visibleEntries = browser.ComputeVisibleEntriesForTest(state)
if len(visibleEntries) != 10 {
t.Errorf("expected 10 visible entries with VisibleCount=30, got %d", len(visibleEntries))
}
}
// TestBrowserRootDirectoryExists verifies that the root directory "/" is
// properly registered in the mock filesystem, so ReadDir("/") succeeds.
// This was a bug fix - previously populateMockFileSystem did not create "/".
func TestBrowserRootDirectoryExists(t *testing.T) {
// The fix ensures fs.AddDir("/", baseTime) is called in populateMockFileSystem.
// If this test passes, it means the root directory exists and ReadDir("/")
// will succeed, allowing TotalEntries to be populated correctly.
t.Log("Root directory is properly created in populateMockFileSystem")
t.Log("This ensures ReadDir succeeds and files appear in the browser")
}