1package cef
2
3import (
4 "context"
5 "testing"
6
7 "github.com/bnema/dumber/internal/application/port"
8 "github.com/bnema/dumber/internal/domain/entity"
9 cefmocks "github.com/bnema/purego-cef/cef/mocks"
10 "github.com/bnema/purego-cef2gtk"
11 "github.com/bnema/puregotk/v4/gdk"
12 "github.com/bnema/puregotk/v4/gtk"
13 "github.com/stretchr/testify/require"
14)
15
16func TestWebViewBridgeInputOptions_LeavesTargetSelectionToAdapter(t *testing.T) {
17 nativeWidget := >k.Widget{}
18 wv := &WebView{
19 nativeWidget: nativeWidget,
20 inputConfig: RuntimeInputConfig{
21 ScrollWheelMultiplier: 1.25,
22 ScrollPreciseMultiplier: 2.5,
23 ScrollHorizontalMultiplier: 0.75,
24 ScrollVerticalMultiplier: 1.5,
25 ScrollMaxDelta: 120,
26 ScrollTouchpadInertia: true,
27 ScrollWheelSmoothing: true,
28 TouchpadNavigationEnabled: true,
29 TouchpadNavigationMinDelta: 80,
30 TouchpadNavigationMaxVerticalRatio: 0.5,
31 },
32 }
33
34 opts := wv.bridgeInputOptions()
35
36 require.Zero(t, opts.Scale)
37 require.InDelta(t, 1.25, opts.Scroll.WheelMultiplier, 0.001)
38 require.InDelta(t, 2.5, opts.Scroll.PreciseMultiplier, 0.001)
39 require.InDelta(t, 0.75, opts.Scroll.HorizontalMultiplier, 0.001)
40 require.InDelta(t, 1.5, opts.Scroll.VerticalMultiplier, 0.001)
41 require.Equal(t, int32(120), opts.Scroll.MaxDelta)
42 require.True(t, opts.Scroll.TouchpadInertia)
43 require.True(t, opts.Scroll.WheelSmoothing)
44 require.NotNil(t, opts.OnMiddleClick)
45 require.NotNil(t, opts.OnScroll)
46 require.False(t, opts.NavigationSwipe.Enabled)
47 require.Zero(t, opts.NavigationSwipe.MinDelta)
48 require.Zero(t, opts.NavigationSwipe.MaxVerticalRatio)
49 require.Nil(t, opts.CanNavigateBack)
50 require.Nil(t, opts.CanNavigateForward)
51 require.Nil(t, opts.OnNavigateSwipe)
52 require.NotNil(t, opts.SelectionText)
53 require.NotNil(t, opts.OnClipboardShortcut)
54 require.Same(t, nativeWidget, wv.nativeWidget)
55}
56
57func TestWebViewHandleScrollInput_ForwardsOrdinaryHorizontalScroll(t *testing.T) {
58 wv := &WebView{
59 ctx: context.Background(),
60 inputConfig: RuntimeInputConfig{
61 TouchpadNavigationEnabled: true,
62 TouchpadNavigationMinDelta: 200,
63 TouchpadNavigationMaxVerticalRatio: 0.5,
64 },
65 canGoBack: true,
66 }
67
68 // This verifies the bridge-level forwarding contract for ordinary scroll
69 // updates. The nil native widget leaves view width unknown, so local history
70 // gesture recognition fails closed and the event continues to CEF.
71 decision := wv.handleScrollInput(cef2gtk.ScrollEvent{
72 Phase: cef2gtk.ScrollPhaseUpdate,
73 X: 500,
74 DX: -240,
75 Unit: gdk.ScrollUnitSurfaceValue,
76 UnitKnown: true,
77 })
78
79 require.Equal(t, cef2gtk.ScrollForwardToCEF, decision)
80}
81
82func TestWebViewHandleScrollInput_EmitsFinalGestureBeforeNavigation(t *testing.T) {
83 browser := cefmocks.NewMockBrowser(t)
84 events := make([]string, 0, 2)
85 browser.EXPECT().GoBack().Run(func() {
86 events = append(events, "go-back")
87 }).Once()
88
89 wv := &WebView{
90 ctx: context.Background(),
91 inputConfig: RuntimeInputConfig{
92 TouchpadNavigationEnabled: true,
93 TouchpadNavigationMinDelta: 200,
94 TouchpadNavigationMaxVerticalRatio: 0.5,
95 },
96 canGoBack: true,
97 browser: browser,
98 callbacks: &port.WebViewCallbacks{
99 OnTouchpadNavigationGesture: func(gesture entity.TouchpadNavigationGesture) {
100 if !gesture.Active && gesture.ThresholdReached {
101 events = append(events, "indicator-finished")
102 }
103 },
104 },
105 }
106
107 begin := wv.handleScrollInput(cef2gtk.ScrollEvent{
108 Phase: cef2gtk.ScrollPhaseBegin,
109 X: 0,
110 Unit: gdk.ScrollUnitSurfaceValue,
111 UnitKnown: true,
112 })
113 require.Equal(t, cef2gtk.ScrollForwardToCEF, begin)
114
115 // Avoid constructing GTK widgets in this package: the WebView integration
116 // only needs a known gesture width after begin records the starting edge.
117 wv.mu.Lock()
118 require.NotNil(t, wv.touchpadNavigation)
119 wv.touchpadNavigation.gestureViewWidth = 1000
120 wv.mu.Unlock()
121
122 update := wv.handleScrollInput(cef2gtk.ScrollEvent{
123 Phase: cef2gtk.ScrollPhaseUpdate,
124 X: 0,
125 DX: -240,
126 Unit: gdk.ScrollUnitSurfaceValue,
127 UnitKnown: true,
128 })
129 require.Equal(t, cef2gtk.ScrollForwardToCEF, update)
130
131 end := wv.handleScrollInput(cef2gtk.ScrollEvent{
132 Phase: cef2gtk.ScrollPhaseEnd,
133 X: 0,
134 Unit: gdk.ScrollUnitSurfaceValue,
135 UnitKnown: true,
136 })
137 require.Equal(t, cef2gtk.ScrollForwardToCEF, end)
138 require.Equal(t, []string{"indicator-finished", "go-back"}, events)
139}