v0.30.0 eb3068f

navigation_webview_targeted_test.go RawHistoryFolder

1package coordinator
2
3import (
4	"context"
5	"testing"
6
7	"github.com/bnema/dumber/internal/application/port"
8	"github.com/bnema/dumber/internal/application/port/mocks"
9	"github.com/bnema/dumber/internal/domain/entity"
10)
11
12type mockDevToolsWebView struct {
13	*mocks.MockWebView
14	*mocks.MockDevToolsOpener
15}
16
17type mockPrinterWebView struct {
18	*mocks.MockWebView
19	*mocks.MockPrinter
20}
21
22// TestNavigationCoordinator_WebViewTargetedActionsUseProvidedWebView verifies that
23// the explicit WebView-targeted navigation methods call the correct methods on the
24// provided WebView rather than resolving through the content coordinator.
25func TestNavigationCoordinator_WebViewTargetedActionsUseProvidedWebView(t *testing.T) {
26	ctx := context.Background()
27
28	t.Run("NavigateWebView with nil webview returns error", func(t *testing.T) {
29		testNavigateWebViewNilWebView(t, ctx)
30	})
31	t.Run("NavigateWebView targets provided webview", func(t *testing.T) {
32		testNavigateWebViewTargetsProvidedWebView(t, ctx)
33	})
34	t.Run("ReloadWebView with nil webview returns error", func(t *testing.T) {
35		testReloadWebViewNilWebView(t, ctx)
36	})
37	t.Run("ReloadWebView bypassCache=false calls Reload once", func(t *testing.T) {
38		testReloadWebViewCallsReload(t, ctx)
39	})
40	t.Run("ReloadWebView bypassCache=true calls ReloadBypassCache once", func(t *testing.T) {
41		testReloadWebViewCallsReloadBypassCache(t, ctx)
42	})
43	t.Run("StopWebView with nil webview returns error", func(t *testing.T) {
44		testStopWebViewNilWebView(t, ctx)
45	})
46	t.Run("StopWebView calls Stop once", func(t *testing.T) {
47		testStopWebViewCallsStop(t, ctx)
48	})
49	t.Run("GoBackWebView with nil webview returns error", func(t *testing.T) {
50		testGoBackWebViewNilWebView(t, ctx)
51	})
52	t.Run("GoBackWebView calls GoBack once", func(t *testing.T) {
53		testGoBackWebViewCallsGoBack(t, ctx)
54	})
55	t.Run("GoForwardWebView with nil webview returns error", func(t *testing.T) {
56		testGoForwardWebViewNilWebView(t, ctx)
57	})
58	t.Run("GoForwardWebView calls GoForward once", func(t *testing.T) {
59		testGoForwardWebViewCallsGoForward(t, ctx)
60	})
61	t.Run("OpenDevToolsWebView with nil webview returns error", func(t *testing.T) {
62		testOpenDevToolsWebViewNilWebView(t, ctx)
63	})
64	t.Run("OpenDevToolsWebView unsupported capability returns error", func(t *testing.T) {
65		testOpenDevToolsWebViewUnsupportedCapability(t, ctx)
66	})
67	t.Run("OpenDevToolsWebView calls OpenDevTools once", func(t *testing.T) {
68		testOpenDevToolsWebViewTargetsProvidedWebView(t, ctx)
69	})
70	t.Run("PrintWebView with nil webview returns error", func(t *testing.T) {
71		testPrintWebViewNilWebView(t, ctx)
72	})
73	t.Run("PrintWebView unsupported capability returns error", func(t *testing.T) {
74		testPrintWebViewUnsupportedCapability(t, ctx)
75	})
76	t.Run("PrintWebView calls PrintPage once", func(t *testing.T) {
77		testPrintWebViewTargetsProvidedWebView(t, ctx)
78	})
79}
80
81func testNavigateWebViewNilWebView(t *testing.T, ctx context.Context) {
82	t.Helper()
83	c := &NavigationCoordinator{}
84	err := c.NavigateWebView(ctx, "https://example.com", entity.PaneID("p1"), nil)
85	if err == nil {
86		t.Fatal("expected error for nil webview, got nil")
87	}
88}
89
90func testNavigateWebViewTargetsProvidedWebView(t *testing.T, ctx context.Context) {
91	t.Helper()
92	wv := mocks.NewMockWebView(t)
93	wv.EXPECT().LoadURI(ctx, "https://example.com").Return(nil).Once()
94	wv.EXPECT().ID().Return(port.WebViewID(42)).Once()
95	c := &NavigationCoordinator{}
96	err := c.NavigateWebView(ctx, "https://example.com", entity.PaneID("p1"), wv)
97	if err != nil {
98		t.Fatalf("unexpected error: %v", err)
99	}
100}
101
102func testReloadWebViewNilWebView(t *testing.T, ctx context.Context) {
103	t.Helper()
104	c := &NavigationCoordinator{}
105	err := c.ReloadWebView(ctx, nil, false)
106	if err == nil {
107		t.Fatal("expected error for nil webview, got nil")
108	}
109}
110
111func testReloadWebViewCallsReload(t *testing.T, ctx context.Context) {
112	t.Helper()
113	wv := mocks.NewMockWebView(t)
114	wv.EXPECT().ID().Return(port.WebViewID(1)).Once()
115	wv.EXPECT().Reload(ctx).Return(nil).Once()
116	c := &NavigationCoordinator{}
117	err := c.ReloadWebView(ctx, wv, false)
118	if err != nil {
119		t.Fatalf("unexpected error: %v", err)
120	}
121}
122
123func testReloadWebViewCallsReloadBypassCache(t *testing.T, ctx context.Context) {
124	t.Helper()
125	wv := mocks.NewMockWebView(t)
126	wv.EXPECT().ID().Return(port.WebViewID(1)).Once()
127	wv.EXPECT().ReloadBypassCache(ctx).Return(nil).Once()
128	c := &NavigationCoordinator{}
129	err := c.ReloadWebView(ctx, wv, true)
130	if err != nil {
131		t.Fatalf("unexpected error: %v", err)
132	}
133}
134
135func testStopWebViewNilWebView(t *testing.T, ctx context.Context) {
136	t.Helper()
137	c := &NavigationCoordinator{}
138	err := c.StopWebView(ctx, nil)
139	if err == nil {
140		t.Fatal("expected error for nil webview, got nil")
141	}
142}
143
144func testStopWebViewCallsStop(t *testing.T, ctx context.Context) {
145	t.Helper()
146	wv := mocks.NewMockWebView(t)
147	wv.EXPECT().ID().Return(port.WebViewID(1)).Once()
148	wv.EXPECT().Stop(ctx).Return(nil).Once()
149	c := &NavigationCoordinator{}
150	err := c.StopWebView(ctx, wv)
151	if err != nil {
152		t.Fatalf("unexpected error: %v", err)
153	}
154}
155
156func testGoBackWebViewNilWebView(t *testing.T, ctx context.Context) {
157	t.Helper()
158	c := &NavigationCoordinator{}
159	err := c.GoBackWebView(ctx, nil)
160	if err == nil {
161		t.Fatal("expected error for nil webview, got nil")
162	}
163}
164
165func testGoBackWebViewCallsGoBack(t *testing.T, ctx context.Context) {
166	t.Helper()
167	wv := mocks.NewMockWebView(t)
168	wv.EXPECT().ID().Return(port.WebViewID(1)).Once()
169	wv.EXPECT().GoBack(ctx).Return(nil).Once()
170	c := &NavigationCoordinator{}
171	err := c.GoBackWebView(ctx, wv)
172	if err != nil {
173		t.Fatalf("unexpected error: %v", err)
174	}
175}
176
177func testGoForwardWebViewNilWebView(t *testing.T, ctx context.Context) {
178	t.Helper()
179	c := &NavigationCoordinator{}
180	err := c.GoForwardWebView(ctx, nil)
181	if err == nil {
182		t.Fatal("expected error for nil webview, got nil")
183	}
184}
185
186func testGoForwardWebViewCallsGoForward(t *testing.T, ctx context.Context) {
187	t.Helper()
188	wv := mocks.NewMockWebView(t)
189	wv.EXPECT().ID().Return(port.WebViewID(1)).Once()
190	wv.EXPECT().GoForward(ctx).Return(nil).Once()
191	c := &NavigationCoordinator{}
192	err := c.GoForwardWebView(ctx, wv)
193	if err != nil {
194		t.Fatalf("unexpected error: %v", err)
195	}
196}
197
198func testOpenDevToolsWebViewNilWebView(t *testing.T, ctx context.Context) {
199	t.Helper()
200	c := &NavigationCoordinator{}
201	err := c.OpenDevToolsWebView(ctx, nil)
202	if err == nil {
203		t.Fatal("expected error for nil webview, got nil")
204	}
205}
206
207func testOpenDevToolsWebViewUnsupportedCapability(t *testing.T, ctx context.Context) {
208	t.Helper()
209	wv := mocks.NewMockWebView(t)
210	wv.EXPECT().ID().Return(port.WebViewID(1)).Once()
211	c := &NavigationCoordinator{}
212	err := c.OpenDevToolsWebView(ctx, wv)
213	if err == nil {
214		t.Fatal("expected unsupported devtools error, got nil")
215	}
216	if got, want := err.Error(), "webview does not support devtools"; got != want {
217		t.Fatalf("error = %q, want %q", got, want)
218	}
219}
220
221func testOpenDevToolsWebViewTargetsProvidedWebView(t *testing.T, ctx context.Context) {
222	t.Helper()
223	base := mocks.NewMockWebView(t)
224	opener := mocks.NewMockDevToolsOpener(t)
225	wv := &mockDevToolsWebView{MockWebView: base, MockDevToolsOpener: opener}
226	base.EXPECT().ID().Return(port.WebViewID(1)).Once()
227	opener.EXPECT().OpenDevTools().Return().Once()
228	c := &NavigationCoordinator{}
229	err := c.OpenDevToolsWebView(ctx, wv)
230	if err != nil {
231		t.Fatalf("unexpected error: %v", err)
232	}
233}
234
235func testPrintWebViewNilWebView(t *testing.T, ctx context.Context) {
236	t.Helper()
237	c := &NavigationCoordinator{}
238	err := c.PrintWebView(ctx, nil)
239	if err == nil {
240		t.Fatal("expected error for nil webview, got nil")
241	}
242}
243
244func testPrintWebViewUnsupportedCapability(t *testing.T, ctx context.Context) {
245	t.Helper()
246	wv := mocks.NewMockWebView(t)
247	wv.EXPECT().ID().Return(port.WebViewID(1)).Once()
248	c := &NavigationCoordinator{}
249	err := c.PrintWebView(ctx, wv)
250	if err == nil {
251		t.Fatal("expected unsupported printing error, got nil")
252	}
253	if got, want := err.Error(), "webview does not support printing"; got != want {
254		t.Fatalf("error = %q, want %q", got, want)
255	}
256}
257
258func testPrintWebViewTargetsProvidedWebView(t *testing.T, ctx context.Context) {
259	t.Helper()
260	base := mocks.NewMockWebView(t)
261	printer := mocks.NewMockPrinter(t)
262	wv := &mockPrinterWebView{MockWebView: base, MockPrinter: printer}
263	base.EXPECT().ID().Return(port.WebViewID(1)).Once()
264	printer.EXPECT().PrintPage().Return().Once()
265	c := &NavigationCoordinator{}
266	err := c.PrintWebView(ctx, wv)
267	if err != nil {
268		t.Fatalf("unexpected error: %v", err)
269	}
270}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close