1package cef
2
3import (
4 "context"
5 "testing"
6
7 "github.com/bnema/dumber/internal/application/port"
8)
9
10type recordingInjectBridge struct {
11 accepted bool
12 calls [][2]float64
13}
14
15func (f *recordingInjectBridge) InjectScroll(dx, dy float64) bool {
16 f.calls = append(f.calls, [2]float64{dx, dy})
17 return f.accepted
18}
19
20func TestScrollPage_SmoothingOn_InjectsImpulse(t *testing.T) {
21 host := &scrollRecorderHost{}
22 fake := &recordingInjectBridge{accepted: true}
23 wv := &WebView{
24 host: host,
25 inputConfig: RuntimeInputConfig{ScrollWheelSmoothing: true},
26 scrollInjectSeam: fake,
27 }
28
29 req := port.PageScrollRequest{
30 Command: port.PageScrollCommandDown,
31 FallbackDX: 0,
32 FallbackDY: 80,
33 }
34 if err := wv.ScrollPage(context.Background(), req); err != nil {
35 t.Fatalf("ScrollPage() unexpected error: %v", err)
36 }
37 if len(fake.calls) != 1 {
38 t.Fatalf("inject calls = %d, want 1", len(fake.calls))
39 }
40 if fake.calls[0][0] != 0 || fake.calls[0][1] != -80 {
41 t.Fatalf("inject deltas = %v, want (0,-80) CEF wheel sign", fake.calls[0])
42 }
43 if len(host.recordedEvents()) != 0 {
44 t.Fatal("injected scroll leaked into the legacy native path")
45 }
46 if q := &wv.pageScrollQueue; q.tapDX != 0 || q.tapDY != 0 || q.heldDX != 0 || q.heldDY != 0 {
47 t.Fatal("injected scroll leaked into the legacy JS queue")
48 }
49}
50
51func TestScrollPage_SmoothingOn_InjectRejectedFallsBack(t *testing.T) {
52 host := &scrollRecorderHost{}
53 fake := &recordingInjectBridge{accepted: false}
54 wv := &WebView{
55 host: host,
56 inputConfig: RuntimeInputConfig{ScrollWheelSmoothing: true},
57 scrollInjectSeam: fake,
58 }
59
60 req := port.PageScrollRequest{
61 Command: port.PageScrollCommandDown,
62 FallbackDX: 0,
63 FallbackDY: 80,
64 }
65 if err := wv.ScrollPage(context.Background(), req); err != nil {
66 t.Fatalf("ScrollPage() unexpected error: %v", err)
67 }
68 if len(host.recordedEvents()) != 1 {
69 t.Fatalf("expected legacy fallback wheel event, got %d", len(host.recordedEvents()))
70 }
71}
72
73func TestScrollPage_SmoothingOff_SkipsInjection(t *testing.T) {
74 host := &scrollRecorderHost{}
75 fake := &recordingInjectBridge{accepted: true}
76 wv := &WebView{
77 host: host,
78 scrollInjectSeam: fake,
79 }
80
81 req := port.PageScrollRequest{
82 Command: port.PageScrollCommandDown,
83 FallbackDX: 0,
84 FallbackDY: 80,
85 }
86 if err := wv.ScrollPage(context.Background(), req); err != nil {
87 t.Fatalf("ScrollPage() unexpected error: %v", err)
88 }
89 if len(fake.calls) != 0 {
90 t.Fatal("injection ran with smoothing disabled")
91 }
92 if len(host.recordedEvents()) != 1 {
93 t.Fatalf("expected legacy wheel event, got %d", len(host.recordedEvents()))
94 }
95}
96
97func TestScrollPage_SmoothingOn_NoBridgeFallsBack(t *testing.T) {
98 host := &scrollRecorderHost{}
99 wv := &WebView{
100 host: host,
101 inputConfig: RuntimeInputConfig{ScrollWheelSmoothing: true},
102 }
103
104 req := port.PageScrollRequest{
105 Command: port.PageScrollCommandUpFast,
106 FallbackDY: -320,
107 }
108 if err := wv.ScrollPage(context.Background(), req); err != nil {
109 t.Fatalf("ScrollPage() unexpected error: %v", err)
110 }
111 events := host.recordedEvents()
112 if len(events) != 1 || events[0].deltaY != 320 {
113 t.Fatalf("expected legacy fallback (0,320), got %+v", events)
114 }
115}