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