Files
ollama/app/tools/browser_test.go
Daniel Hiltgen d3b4b9970a app: add code for macOS and Windows apps under 'app' (#12933)
* app: add code for macOS and Windows apps under 'app'

* app: add readme

* app: windows and linux only for now

* ci: fix ui CI validation

---------

Co-authored-by: jmorganca <jmorganca@gmail.com>
2025-11-04 11:40:17 -08:00

148 lines
4.9 KiB
Go

//go:build windows || darwin
package tools
import (
"strings"
"testing"
"time"
"github.com/ollama/ollama/app/ui/responses"
)
func makeTestPage(url string) *responses.Page {
return &responses.Page{
URL: url,
Title: "Title " + url,
Text: "Body for " + url,
Lines: []string{"line1", "line2", "line3"},
Links: map[int]string{0: url},
FetchedAt: time.Now(),
}
}
func TestBrowser_Scroll_AppendsOnlyPageStack(t *testing.T) {
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
p1 := makeTestPage("https://example.com/1")
b.savePage(p1)
initialStackLen := len(b.state.Data.PageStack)
initialMapLen := len(b.state.Data.URLToPage)
bo := NewBrowserOpen(b)
// Scroll without id — should push only to PageStack
_, _, err := bo.Execute(t.Context(), map[string]any{"loc": float64(1), "num_lines": float64(1)})
if err != nil {
t.Fatalf("scroll execute failed: %v", err)
}
if got, want := len(b.state.Data.PageStack), initialStackLen+1; got != want {
t.Fatalf("page stack length = %d, want %d", got, want)
}
if got, want := len(b.state.Data.URLToPage), initialMapLen; got != want {
t.Fatalf("url_to_page length changed = %d, want %d", got, want)
}
}
func TestBrowserOpen_UseCacheByURL(t *testing.T) {
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
bo := NewBrowserOpen(b)
p := makeTestPage("https://example.com/cached")
b.state.Data.URLToPage[p.URL] = p
initialStackLen := len(b.state.Data.PageStack)
initialMapLen := len(b.state.Data.URLToPage)
_, _, err := bo.Execute(t.Context(), map[string]any{"id": p.URL})
if err != nil {
t.Fatalf("open cached execute failed: %v", err)
}
if got, want := len(b.state.Data.PageStack), initialStackLen+1; got != want {
t.Fatalf("page stack length = %d, want %d", got, want)
}
if got, want := len(b.state.Data.URLToPage), initialMapLen; got != want {
t.Fatalf("url_to_page length changed = %d, want %d", got, want)
}
}
func TestDisplayPage_InvalidLoc(t *testing.T) {
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
p := makeTestPage("https://example.com/x")
// ensure lines are set
p.Lines = []string{"a", "b"}
_, err := b.displayPage(p, 0, 10, -1)
if err == nil || !strings.Contains(err.Error(), "invalid location") {
t.Fatalf("expected invalid location error, got %v", err)
}
}
func TestBrowserOpen_LinkId_UsesCacheAndAppends(t *testing.T) {
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
// Seed a main page with a link id 0 to a linked URL
main := makeTestPage("https://example.com/main")
linked := makeTestPage("https://example.com/linked")
main.Links = map[int]string{0: linked.URL}
// Save the main page (adds to PageStack and URLToPage)
b.savePage(main)
// Pre-cache the linked page so open by id avoids network
b.state.Data.URLToPage[linked.URL] = linked
initialStackLen := len(b.state.Data.PageStack)
initialMapLen := len(b.state.Data.URLToPage)
bo := NewBrowserOpen(b)
_, _, err := bo.Execute(t.Context(), map[string]any{"id": float64(0)})
if err != nil {
t.Fatalf("open by link id failed: %v", err)
}
if got, want := len(b.state.Data.PageStack), initialStackLen+1; got != want {
t.Fatalf("page stack length = %d, want %d", got, want)
}
if got, want := len(b.state.Data.URLToPage), initialMapLen; got != want {
t.Fatalf("url_to_page length changed = %d, want %d", got, want)
}
if last := b.state.Data.PageStack[len(b.state.Data.PageStack)-1]; last != linked.URL {
t.Fatalf("last page in stack = %s, want %s", last, linked.URL)
}
}
func TestWrapLines_PreserveAndWidth(t *testing.T) {
long := strings.Repeat("word ", 50)
text := "Line1\n\n" + long + "\nLine3"
lines := wrapLines(text, 40)
// Ensure empty line preserved at index 1
if lines[1] != "" {
t.Fatalf("expected preserved empty line at index 1, got %q", lines[1])
}
// All lines should be <= 40 chars
for i, l := range lines {
if len(l) > 40 {
t.Fatalf("line %d exceeds width: %d > 40", i, len(l))
}
}
}
func TestDisplayPage_FormatHeaderAndLines(t *testing.T) {
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
p := &responses.Page{
URL: "https://example.com/x",
Title: "Example",
Lines: []string{"URL: https://example.com/x", "A", "B", "C"},
}
out, err := b.displayPage(p, 3, 0, 2)
if err != nil {
t.Fatalf("displayPage failed: %v", err)
}
if !strings.HasPrefix(out, "[3] Example(") {
t.Fatalf("header not formatted as expected: %q", out)
}
if !strings.Contains(out, "L0:\n") {
t.Fatalf("missing L0 label: %q", out)
}
if !strings.Contains(out, "L1: URL: https://example.com/x\n") || !strings.Contains(out, "L2: A\n") {
t.Fatalf("missing expected line numbers/content: %q", out)
}
}