1package cef
2
3import (
4 "context"
5 "testing"
6 "time"
7
8 purecef "github.com/bnema/purego-cef/cef"
9 cefmocks "github.com/bnema/purego-cef/cef/mocks"
10 "github.com/stretchr/testify/require"
11)
12
13func TestWebViewReplayPendingNavigation_LoadsQueuedURIWhenMainFrameAvailable(t *testing.T) {
14 browser := cefmocks.NewMockBrowser(t)
15 frame := cefmocks.NewMockFrame(t)
16 frame.EXPECT().GetURL().Return("").Once()
17 frame.EXPECT().LoadURL("https://github.com/bnema").Once()
18 browser.EXPECT().GetMainFrame().Return(frame).Once()
19
20 wv := &WebView{ctx: context.Background(), browser: browser, pendingURI: "https://github.com/bnema"}
21 wv.replayPendingNavigation(0)
22
23 wv.mu.RLock()
24 defer wv.mu.RUnlock()
25 require.Equal(t, "https://github.com/bnema", wv.pendingURI)
26}
27
28func TestWebViewReplayPendingNavigation_RetriesWhenMainFrameUnavailable(t *testing.T) {
29 browser := cefmocks.NewMockBrowser(t)
30 browser.EXPECT().GetMainFrame().Return(purecef.Frame(nil)).Once()
31
32 oldTask := cefNewTask
33 oldDelayed := cefPostDelayedTask
34 defer func() {
35 cefNewTask = oldTask
36 cefPostDelayedTask = oldDelayed
37 }()
38 cefNewTask = func(task purecef.Task) purecef.Task { return task }
39
40 scheduled := false
41 cefPostDelayedTask = func(threadID purecef.ThreadID, task purecef.Task, delayMs int64) int32 {
42 require.Equal(t, purecef.ThreadIDTidUi, threadID)
43 require.NotNil(t, task)
44 require.Equal(t, int64(pendingNavigationRetryDelay/time.Millisecond), delayMs)
45 scheduled = true
46 return 1
47 }
48
49 wv := &WebView{ctx: context.Background(), browser: browser, pendingURI: "https://github.com/bnema"}
50 wv.replayPendingNavigation(0)
51
52 require.True(t, scheduled)
53 wv.mu.RLock()
54 defer wv.mu.RUnlock()
55 require.Equal(t, "https://github.com/bnema", wv.pendingURI)
56}
57
58func TestWebViewSchedulePendingNavigationReplay_RetriesWhenTaskPostFails(t *testing.T) {
59 browser := cefmocks.NewMockBrowser(t)
60
61 oldTask := cefNewTask
62 oldPost := cefPostTask
63 oldDelayed := cefPostDelayedTask
64 oldAfter := cefScheduleAfter
65 defer func() {
66 cefNewTask = oldTask
67 cefPostTask = oldPost
68 cefPostDelayedTask = oldDelayed
69 cefScheduleAfter = oldAfter
70 }()
71 cefNewTask = func(task purecef.Task) purecef.Task { return task }
72
73 retried := false
74 cefPostTask = func(threadID purecef.ThreadID, task purecef.Task) int32 {
75 require.Equal(t, purecef.ThreadIDTidUi, threadID)
76 require.NotNil(t, task)
77 return 0
78 }
79 cefScheduleAfter = func(delay time.Duration, fn func()) {
80 require.Equal(t, pendingNavigationRetryDelay, delay)
81 fn()
82 }
83 cefPostDelayedTask = func(threadID purecef.ThreadID, task purecef.Task, delayMs int64) int32 {
84 require.Equal(t, purecef.ThreadIDTidUi, threadID)
85 require.NotNil(t, task)
86 require.Equal(t, int64(pendingNavigationRetryDelay/time.Millisecond), delayMs)
87 retried = true
88 return 1
89 }
90
91 wv := &WebView{ctx: context.Background(), browser: browser, pendingURI: "https://github.com/bnema"}
92 wv.schedulePendingNavigationReplay(0)
93
94 require.True(t, retried)
95}
96
97func TestWebViewReplayPendingNavigation_UsesCurrentBrowserAtExecutionTime(t *testing.T) {
98 staleBrowser := cefmocks.NewMockBrowser(t)
99 activeBrowser := cefmocks.NewMockBrowser(t)
100 frame := cefmocks.NewMockFrame(t)
101 frame.EXPECT().GetURL().Return("").Once()
102 frame.EXPECT().LoadURL("https://github.com/bnema").Once()
103 activeBrowser.EXPECT().GetMainFrame().Return(frame).Once()
104
105 oldTask := cefNewTask
106 oldPost := cefPostTask
107 defer func() {
108 cefNewTask = oldTask
109 cefPostTask = oldPost
110 }()
111 var scheduled purecef.Task
112 cefNewTask = func(task purecef.Task) purecef.Task { return task }
113 cefPostTask = func(threadID purecef.ThreadID, task purecef.Task) int32 {
114 require.Equal(t, purecef.ThreadIDTidUi, threadID)
115 scheduled = task
116 return 1
117 }
118
119 wv := &WebView{ctx: context.Background(), browser: staleBrowser, pendingURI: "https://github.com/bnema"}
120 wv.schedulePendingNavigationReplay(0)
121 wv.mu.Lock()
122 wv.browser = activeBrowser
123 wv.mu.Unlock()
124
125 require.NotNil(t, scheduled)
126 scheduled.Execute()
127}
128
129func TestWebViewLoadURI_QueuesPendingNavigationReplayForExistingBrowser(t *testing.T) {
130 browser := cefmocks.NewMockBrowser(t)
131 frame := cefmocks.NewMockFrame(t)
132 browser.EXPECT().GetMainFrame().Return(frame).Once()
133 frame.EXPECT().GetURL().Return("").Once()
134 frame.EXPECT().LoadURL("github.com/bnema").Once()
135
136 oldTask := cefNewTask
137 oldPost := cefPostTask
138 defer func() {
139 cefNewTask = oldTask
140 cefPostTask = oldPost
141 }()
142 cefNewTask = func(task purecef.Task) purecef.Task { return task }
143 cefPostTask = func(threadID purecef.ThreadID, task purecef.Task) int32 {
144 require.Equal(t, purecef.ThreadIDTidUi, threadID)
145 require.NotNil(t, task)
146 task.Execute()
147 return 1
148 }
149
150 wv := &WebView{ctx: context.Background(), browser: browser}
151 require.NoError(t, wv.LoadURI(context.Background(), "github.com/bnema"))
152
153 wv.mu.RLock()
154 defer wv.mu.RUnlock()
155 require.Equal(t, "github.com/bnema", wv.pendingURI)
156}
157
158func TestWebViewUpdateURI_ClearsMatchingPendingNavigation(t *testing.T) {
159 wv := &WebView{ctx: context.Background(), pendingURI: "https://github.com/bnema"}
160
161 wv.updateURI("https://github.com/bnema")
162
163 require.Empty(t, wv.pendingNavigationURI())
164}