1package cef
2
3import (
4 "context"
5 "strings"
6 "testing"
7 "unsafe"
8
9 purecef "github.com/bnema/purego-cef/cef"
10)
11
12type schemeRegistrarStub struct {
13 scheme string
14 options int32
15 calls int
16}
17
18func (s *schemeRegistrarStub) AddCustomScheme(schemeName string, options int32) int32 {
19 s.calls++
20 s.scheme = schemeName
21 s.options = options
22 return 1
23}
24
25type relaunchCommandLineStub struct {
26 commandLineString string
27}
28
29func (c relaunchCommandLineStub) IsValid() bool { return true }
30func (c relaunchCommandLineStub) IsReadOnly() bool { return true }
31func (c relaunchCommandLineStub) Copy() purecef.CommandLine { return c }
32func (c relaunchCommandLineStub) InitFromArgv(int32, unsafe.Pointer) {}
33func (c relaunchCommandLineStub) InitFromString(string) {}
34func (c relaunchCommandLineStub) Reset() {}
35func (c relaunchCommandLineStub) GetArgv(purecef.StringList) {}
36func (c relaunchCommandLineStub) GetCommandLineString() string { return c.commandLineString }
37func (c relaunchCommandLineStub) GetProgram() string { return "dumber" }
38func (c relaunchCommandLineStub) SetProgram(string) {}
39func (c relaunchCommandLineStub) HasSwitches() bool { return false }
40func (c relaunchCommandLineStub) HasSwitch(string) bool { return false }
41func (c relaunchCommandLineStub) GetSwitchValue(string) string { return "" }
42func (c relaunchCommandLineStub) GetSwitches(purecef.StringMap) {}
43func (c relaunchCommandLineStub) AppendSwitch(string) {}
44func (c relaunchCommandLineStub) AppendSwitchWithValue(string, string) {
45}
46func (c relaunchCommandLineStub) HasArguments() bool { return true }
47func (c relaunchCommandLineStub) GetArguments(purecef.StringList) {}
48func (c relaunchCommandLineStub) AppendArgument(string) {
49}
50func (c relaunchCommandLineStub) PrependWrapper(string) {}
51func (c relaunchCommandLineStub) RemoveSwitch(string) {}
52
53type mutableCommandLineStub struct {
54 relaunchCommandLineStub
55 switches map[string]string
56}
57
58func newMutableCommandLineStub() *mutableCommandLineStub {
59 return &mutableCommandLineStub{switches: make(map[string]string)}
60}
61
62func (c *mutableCommandLineStub) IsReadOnly() bool { return false }
63func (c *mutableCommandLineStub) Copy() purecef.CommandLine { return c }
64func (c *mutableCommandLineStub) Reset() { c.switches = make(map[string]string) }
65func (c *mutableCommandLineStub) HasSwitches() bool { return len(c.switches) > 0 }
66func (c *mutableCommandLineStub) HasSwitch(name string) bool {
67 _, ok := c.switches[name]
68 return ok
69}
70func (c *mutableCommandLineStub) GetSwitchValue(name string) string { return c.switches[name] }
71func (c *mutableCommandLineStub) AppendSwitch(name string) { c.switches[name] = "" }
72func (c *mutableCommandLineStub) AppendSwitchWithValue(name, value string) {
73 c.switches[name] = value
74}
75func (c *mutableCommandLineStub) HasArguments() bool { return false }
76func (c *mutableCommandLineStub) RemoveSwitch(name string) {
77 delete(c.switches, name)
78}
79
80func TestRegisterDumbScheme(t *testing.T) {
81 t.Parallel()
82
83 stub := &schemeRegistrarStub{}
84 registerDumbScheme(stub)
85
86 wantOptions := purecef.SchemeOptionsSchemeOptionStandard |
87 purecef.SchemeOptionsSchemeOptionSecure |
88 purecef.SchemeOptionsSchemeOptionCorsEnabled |
89 purecef.SchemeOptionsSchemeOptionCspBypassing |
90 purecef.SchemeOptionsSchemeOptionFetchEnabled
91
92 if stub.calls != 1 {
93 t.Fatalf("AddCustomScheme call count = %d, want 1", stub.calls)
94 }
95 if stub.scheme != dumbSchemeName {
96 t.Fatalf("scheme = %q, want %q", stub.scheme, dumbSchemeName)
97 }
98 if stub.options != wantOptions {
99 t.Fatalf("options = %d, want %d", stub.options, wantOptions)
100 }
101}
102
103func TestParseBrowseURLFromRelaunchCommandLine(t *testing.T) {
104 t.Parallel()
105
106 got := parseBrowseURLFromRelaunchCommandLine(relaunchCommandLineStub{
107 commandLineString: "dumber browse https://example.com",
108 })
109
110 if got != "https://example.com" {
111 t.Fatalf("parsed browse url = %q, want %q", got, "https://example.com")
112 }
113}
114
115func TestParseBrowseURLFromRelaunchCommandLineWithInstanceFlag(t *testing.T) {
116 t.Parallel()
117
118 for _, commandLine := range []string{
119 "dumber browse --instance work https://example.com",
120 "dumber browse https://example.com --instance=work",
121 } {
122 got := parseBrowseURLFromRelaunchCommandLine(relaunchCommandLineStub{commandLineString: commandLine})
123 if got != "https://example.com" {
124 t.Fatalf("parsed browse url from %q = %q", commandLine, got)
125 }
126 }
127}
128
129func TestParseBrowseRelaunchCommandLineRejectsCrossProfileLaunches(t *testing.T) {
130 t.Parallel()
131
132 for _, commandLine := range []string{
133 "dumber browse --profile work https://example.com",
134 "dumber browse --profile=work https://example.com",
135 "dumber browse --ephemeral https://example.com",
136 } {
137 if got, ok := parseBrowseRelaunchCommandLine(relaunchCommandLineStub{commandLineString: commandLine}); ok || got != "" {
138 t.Fatalf("parseBrowseRelaunchCommandLine(%q) = (%q, %v), want rejected", commandLine, got, ok)
139 }
140 }
141}
142
143func TestDumberBPH_OnAlreadyRunningAppRelaunch_ForwardsBrowseURLAndReturns1(t *testing.T) {
144 t.Parallel()
145
146 gotURL := ""
147 eng := &Engine{}
148 eng.SetAlreadyRunningAppRelaunchHandler(func(url string) {
149 gotURL = url
150 })
151
152 ret := (&dumberBPH{engine: eng}).OnAlreadyRunningAppRelaunch(relaunchCommandLineStub{
153 commandLineString: "dumber browse https://example.com",
154 }, "")
155
156 if ret != 1 {
157 t.Fatalf("OnAlreadyRunningAppRelaunch returned %d, want 1", ret)
158 }
159 if gotURL != "https://example.com" {
160 t.Fatalf("forwarded browse url = %q, want %q", gotURL, "https://example.com")
161 }
162}
163
164func TestDumberBPH_OnAlreadyRunningAppRelaunch_DoesNotForwardEmptyBrowseURLAndReturns1(t *testing.T) {
165 t.Parallel()
166
167 gotURL := "sentinel"
168 eng := &Engine{}
169 eng.SetAlreadyRunningAppRelaunchHandler(func(url string) {
170 gotURL = url
171 })
172
173 ret := (&dumberBPH{engine: eng}).OnAlreadyRunningAppRelaunch(relaunchCommandLineStub{
174 commandLineString: "dumber browse",
175 }, "")
176
177 if ret != 1 {
178 t.Fatalf("OnAlreadyRunningAppRelaunch returned %d, want 1", ret)
179 }
180 if gotURL != "sentinel" {
181 t.Fatalf("forwarded browse url = %q, want %q", gotURL, "sentinel")
182 }
183}
184
185func TestDumberBPH_OnAlreadyRunningAppRelaunch_DoesNotForwardNonBrowse(t *testing.T) {
186 t.Parallel()
187
188 called := false
189 eng := &Engine{}
190 eng.SetAlreadyRunningAppRelaunchHandler(func(string) {
191 called = true
192 })
193
194 ret := (&dumberBPH{engine: eng}).OnAlreadyRunningAppRelaunch(relaunchCommandLineStub{
195 commandLineString: "dumber",
196 }, "")
197
198 if ret != 0 {
199 t.Fatalf("OnAlreadyRunningAppRelaunch returned %d, want 0", ret)
200 }
201 if called {
202 t.Fatal("handler should not be called for non-browse relaunch")
203 }
204}
205
206func TestConfigureCommandLine_AppendsExpectedSwitches(t *testing.T) {
207 commandLine := newMutableCommandLineStub()
208 configureCommandLine(commandLine)
209
210 if !commandLine.HasSwitch("enable-smooth-scrolling") {
211 t.Fatal("expected enable-smooth-scrolling switch to be appended")
212 }
213 if got := commandLine.GetSwitchValue("autoplay-policy"); got != "no-user-gesture-required" {
214 t.Fatalf("autoplay-policy = %q, want %q", got, "no-user-gesture-required")
215 }
216}
217
218func TestConfigureCommandLine_DisablesWebAuthnByDefault(t *testing.T) {
219 t.Setenv(cefEnableWebAuthnUnsafeEnvVar, "")
220
221 commandLine := newMutableCommandLineStub()
222 configureCommandLine(commandLine)
223
224 want := "WebAuth"
225 if got := commandLine.GetSwitchValue(chromiumDisableFeaturesSwitch); got != want {
226 t.Fatalf("disable-features = %q, want %q", got, want)
227 }
228 if got := commandLine.GetSwitchValue(chromiumDisableBlinkFeaturesSwitch); got != want {
229 t.Fatalf("disable-blink-features = %q, want %q", got, want)
230 }
231}
232
233func TestConfigureCommandLine_WebAuthnUnsafeOptInDoesNotDisableWebAuth(t *testing.T) {
234 t.Setenv(cefEnableWebAuthnUnsafeEnvVar, "1")
235
236 commandLine := newMutableCommandLineStub()
237 configureCommandLine(commandLine)
238
239 if got := commandLine.GetSwitchValue(chromiumDisableFeaturesSwitch); strings.Contains(got, "WebAuth") {
240 t.Fatalf("disable-features = %q, should not contain WebAuth", got)
241 }
242 if got := commandLine.GetSwitchValue(chromiumDisableBlinkFeaturesSwitch); strings.Contains(got, "WebAuth") {
243 t.Fatalf("disable-blink-features = %q, should not contain WebAuth", got)
244 }
245}
246
247func TestConfigureCommandLine_WebAuthnDisablePreservesExistingDisableFeatures(t *testing.T) {
248 commandLine := newMutableCommandLineStub()
249 commandLine.AppendSwitchWithValue(chromiumDisableFeaturesSwitch, "ExistingFeature,WebAuth")
250 commandLine.AppendSwitchWithValue(chromiumDisableBlinkFeaturesSwitch, "ExistingBlinkFeature,WebAuth")
251
252 configureCommandLine(commandLine)
253
254 if got := commandLine.GetSwitchValue(chromiumDisableFeaturesSwitch); got != "ExistingFeature,WebAuth" {
255 t.Fatalf("disable-features = %q, want %q", got, "ExistingFeature,WebAuth")
256 }
257 if got := commandLine.GetSwitchValue(chromiumDisableBlinkFeaturesSwitch); got != "ExistingBlinkFeature,WebAuth" {
258 t.Fatalf("disable-blink-features = %q, want %q", got, "ExistingBlinkFeature,WebAuth")
259 }
260}
261
262func TestConfigureCommandLine_WebAuthnUnsafeOverrideRemovesExistingWebAuthTokens(t *testing.T) {
263 t.Setenv(cefEnableWebAuthnUnsafeEnvVar, "1")
264
265 commandLine := newMutableCommandLineStub()
266 commandLine.AppendSwitchWithValue(chromiumDisableFeaturesSwitch, "ExistingFeature,WebAuth,AnotherFeature")
267 commandLine.AppendSwitchWithValue(chromiumDisableBlinkFeaturesSwitch, "WebAuth,ExistingBlinkFeature")
268
269 configureCommandLine(commandLine)
270
271 if got := commandLine.GetSwitchValue(chromiumDisableFeaturesSwitch); got != "ExistingFeature,AnotherFeature" {
272 t.Fatalf("disable-features = %q, want %q", got, "ExistingFeature,AnotherFeature")
273 }
274 if got := commandLine.GetSwitchValue(chromiumDisableBlinkFeaturesSwitch); got != "ExistingBlinkFeature" {
275 t.Fatalf("disable-blink-features = %q, want %q", got, "ExistingBlinkFeature")
276 }
277}
278
279func TestConfigureCommandLine_WebAuthnUnsafeOverrideRemovesSwitchWhenOnlyWebAuth(t *testing.T) {
280 t.Setenv(cefEnableWebAuthnUnsafeEnvVar, "1")
281
282 commandLine := newMutableCommandLineStub()
283 commandLine.AppendSwitchWithValue(chromiumDisableFeaturesSwitch, "WebAuth")
284
285 configureCommandLine(commandLine)
286
287 if commandLine.HasSwitch(chromiumDisableFeaturesSwitch) {
288 t.Fatalf("disable-features switch should have been removed entirely, but has value %q", commandLine.GetSwitchValue(chromiumDisableFeaturesSwitch))
289 }
290}
291
292func TestConfigureCommandLine_SetsOzonePlatformToWayland(t *testing.T) {
293 commandLine := newMutableCommandLineStub()
294 configureCommandLine(commandLine)
295
296 if got := commandLine.GetSwitchValue("ozone-platform"); got != "wayland" {
297 t.Fatalf("ozone-platform = %q, want %q", got, "wayland")
298 }
299
300 // Dumber-specific switches must remain present.
301 if !commandLine.HasSwitch("enable-smooth-scrolling") {
302 t.Fatal("expected enable-smooth-scrolling switch to be present")
303 }
304 if got := commandLine.GetSwitchValue("autoplay-policy"); got != "no-user-gesture-required" {
305 t.Fatalf("autoplay-policy = %q, want %q", got, "no-user-gesture-required")
306 }
307}
308
309func TestConfigureCommandLine_PreservesExistingOzonePlatform(t *testing.T) {
310 commandLine := newMutableCommandLineStub()
311 commandLine.AppendSwitchWithValue("ozone-platform", "x11")
312
313 configureCommandLine(commandLine)
314
315 if got := commandLine.GetSwitchValue("ozone-platform"); got != "x11" {
316 t.Fatalf("ozone-platform = %q, want %q (bridge preserves existing value)", got, "x11")
317 }
318
319 // Dumber-specific switches must remain present.
320 if !commandLine.HasSwitch("enable-smooth-scrolling") {
321 t.Fatal("expected enable-smooth-scrolling switch to be present")
322 }
323 if got := commandLine.GetSwitchValue("autoplay-policy"); got != "no-user-gesture-required" {
324 t.Fatalf("autoplay-policy = %q, want %q", got, "no-user-gesture-required")
325 }
326}
327
328func TestConfigureCommandLine_PreservesInheritedANGLEBackend(t *testing.T) {
329 commandLine := newMutableCommandLineStub()
330 commandLine.AppendSwitchWithValue("use-angle", "gl-egl")
331
332 configureCommandLine(commandLine)
333
334 if got := commandLine.GetSwitchValue("use-angle"); got != "gl-egl" {
335 t.Fatalf("use-angle = %q, want inherited gl-egl", got)
336 }
337}
338
339func TestConfigureCommandLine_EnableVAAPIEnvAppendsHardwareDecodeFlags(t *testing.T) {
340 t.Setenv(cefEnableVAAPIEnvVar, "1")
341
342 commandLine := newMutableCommandLineStub()
343 commandLine.AppendSwitchWithValue(chromiumEnableFeaturesSwitch, "ExistingFeature")
344
345 configureCommandLine(commandLine)
346
347 gotFeatures := commandLine.GetSwitchValue(chromiumEnableFeaturesSwitch)
348 for _, feature := range []string{
349 "ExistingFeature",
350 "AcceleratedVideoDecoder",
351 "AcceleratedVideoEncoder",
352 "AcceleratedVideoDecodeLinuxGL",
353 "AcceleratedVideoDecodeLinuxZeroCopyGL",
354 "VaapiIgnoreDriverChecks",
355 } {
356 if !strings.Contains(gotFeatures, feature) {
357 t.Fatalf("enable-features = %q, missing %q", gotFeatures, feature)
358 }
359 }
360 if !commandLine.HasSwitch("ignore-gpu-blocklist") {
361 t.Fatal("expected ignore-gpu-blocklist switch")
362 }
363 if !commandLine.HasSwitch("enable-zero-copy") {
364 t.Fatal("expected enable-zero-copy switch")
365 }
366 if !commandLine.HasSwitch("disable-gpu-driver-bug-workaround") {
367 t.Fatal("expected disable-gpu-driver-bug-workaround switch")
368 }
369}
370
371func TestConfigureCommandLine_ChromiumFlagsEnvAppendsSwitches(t *testing.T) {
372 t.Setenv(cefChromiumFlagsEnvVar, `--enable-features=VaapiVideoDecoder,VaapiIgnoreDriverChecks --ignore-gpu-blocklist --autoplay-policy=document-user-activation-required ignored-arg`)
373
374 commandLine := newMutableCommandLineStub()
375 commandLine.AppendSwitchWithValue(chromiumEnableFeaturesSwitch, "ExistingFeature")
376
377 configureCommandLine(commandLine)
378
379 if got := commandLine.GetSwitchValue(chromiumEnableFeaturesSwitch); got != "ExistingFeature,Vulkan,DefaultANGLEVulkan,VulkanFromANGLE,VaapiVideoDecoder,VaapiIgnoreDriverChecks" {
380 t.Fatalf("enable-features = %q, want render stack and env features appended", got)
381 }
382 if !commandLine.HasSwitch("ignore-gpu-blocklist") {
383 t.Fatal("expected ignore-gpu-blocklist switch")
384 }
385 if got := commandLine.GetSwitchValue("autoplay-policy"); got != "document-user-activation-required" {
386 t.Fatalf("autoplay-policy = %q, want env override", got)
387 }
388 if commandLine.HasSwitch("ignored-arg") {
389 t.Fatal("non-switch env token should be ignored")
390 }
391}
392
393func TestParseChromiumSwitchToken(t *testing.T) {
394 t.Parallel()
395
396 tests := []struct {
397 name string
398 token string
399 wantName string
400 wantValue string
401 wantOK bool
402 }{
403 {name: "long switch with value", token: "--enable-features=VaapiVideoDecoder", wantName: "enable-features", wantValue: "VaapiVideoDecoder", wantOK: true},
404 {name: "long switch without value", token: "--ignore-gpu-blocklist", wantName: "ignore-gpu-blocklist", wantOK: true},
405 {name: "single dash switch", token: "-enable-zero-copy", wantName: "enable-zero-copy", wantOK: true},
406 {name: "empty value", token: "--flag=", wantName: "flag", wantOK: true},
407 {name: "embedded equals", token: "--flag=a=b", wantName: "flag", wantValue: "a=b", wantOK: true},
408 {name: "non switch", token: "youtube.com", wantOK: false},
409 {name: "sentinel", token: "--", wantOK: false},
410 {name: "empty", token: " ", wantOK: false},
411 }
412
413 for _, tt := range tests {
414 t.Run(tt.name, func(t *testing.T) {
415 gotName, gotValue, gotOK := parseChromiumSwitchToken(tt.token)
416 if gotName != tt.wantName || gotValue != tt.wantValue || gotOK != tt.wantOK {
417 t.Fatalf("parseChromiumSwitchToken(%q) = (%q, %q, %v), want (%q, %q, %v)", tt.token, gotName, gotValue, gotOK, tt.wantName, tt.wantValue, tt.wantOK)
418 }
419 })
420 }
421}
422
423func TestAppendUniqueCommaSeparatedSwitchValues(t *testing.T) {
424 t.Run("trims whitespace and skips empty existing values", func(t *testing.T) {
425 commandLine := newMutableCommandLineStub()
426 commandLine.AppendSwitchWithValue("disable-features", " , ExistingFeature , ")
427
428 appendUniqueCommaSeparatedSwitchValues(commandLine, "disable-features", "FeatureA")
429
430 want := "ExistingFeature,FeatureA"
431 if got := commandLine.GetSwitchValue("disable-features"); got != want {
432 t.Fatalf("disable-features = %q, want %q", got, want)
433 }
434 })
435
436 t.Run("deduplicates existing and appended values", func(t *testing.T) {
437 commandLine := newMutableCommandLineStub()
438 commandLine.AppendSwitchWithValue("disable-features", "FeatureA,FeatureA")
439
440 appendUniqueCommaSeparatedSwitchValues(commandLine, "disable-features", "FeatureA", "FeatureB")
441
442 want := "FeatureA,FeatureB"
443 if got := commandLine.GetSwitchValue("disable-features"); got != want {
444 t.Fatalf("disable-features = %q, want %q", got, want)
445 }
446 })
447
448 t.Run("empty appended values are no-op", func(t *testing.T) {
449 commandLine := newMutableCommandLineStub()
450 commandLine.AppendSwitchWithValue("disable-features", "ExistingFeature")
451
452 appendUniqueCommaSeparatedSwitchValues(commandLine, "disable-features")
453
454 if got := commandLine.GetSwitchValue("disable-features"); got != "ExistingFeature" {
455 t.Fatalf("disable-features = %q, want ExistingFeature", got)
456 }
457 })
458
459 t.Run("nil command line is no-op", func(_ *testing.T) {
460 appendUniqueCommaSeparatedSwitchValues(nil, "disable-features", "FeatureA")
461 })
462}
463
464func TestDumberBPH_OnBeforeChildProcessLaunch_AppendsNoZygote(t *testing.T) {
465 commandLine := newMutableCommandLineStub()
466 commandLine.AppendSwitchWithValue("type", "renderer")
467
468 (&dumberBPH{engine: &Engine{ctx: context.Background()}}).OnBeforeChildProcessLaunch(commandLine)
469
470 if !commandLine.HasSwitch("no-zygote") {
471 t.Fatal("expected no-zygote switch to be appended for child processes")
472 }
473}
474
475func TestConfigureCommandLine_CEFRenderNodeEnvOverridesExistingRenderNode(t *testing.T) {
476 t.Setenv(cefRenderNodeEnvVar, "/dev/dri/renderD129")
477
478 commandLine := newMutableCommandLineStub()
479 commandLine.AppendSwitchWithValue(chromiumRenderNodeOverrideSwitch, "/dev/dri/renderD128")
480
481 configureCommandLine(commandLine)
482
483 if got := commandLine.GetSwitchValue(chromiumRenderNodeOverrideSwitch); got != "/dev/dri/renderD129" {
484 t.Fatalf("render node override = %q, want /dev/dri/renderD129", got)
485 }
486}
487
488func TestConfigureCommandLine_CEFRenderNodeEnvSentinelsRemoveExistingRenderNode(t *testing.T) {
489 for _, value := range []string{"auto", "default", "none", "off", "disable", "disabled"} {
490 t.Run(value, func(t *testing.T) {
491 t.Setenv(cefRenderNodeEnvVar, value)
492
493 commandLine := newMutableCommandLineStub()
494 commandLine.AppendSwitchWithValue(chromiumRenderNodeOverrideSwitch, "/dev/dri/renderD128")
495
496 configureCommandLine(commandLine)
497
498 if commandLine.HasSwitch(chromiumRenderNodeOverrideSwitch) {
499 t.Fatalf("render node override still present: %q", commandLine.GetSwitchValue(chromiumRenderNodeOverrideSwitch))
500 }
501 })
502 }
503}
504
505func TestDumberBPH_OnBeforeChildProcessLaunch_AppliesRenderingAndHardwareDecodeFlags(t *testing.T) {
506 t.Setenv(cef2gtkAngleBackendVar, "vulkan")
507 t.Setenv(cefEnableVAAPIEnvVar, "1")
508
509 commandLine := newMutableCommandLineStub()
510 commandLine.AppendSwitchWithValue("type", "gpu-process")
511 commandLine.AppendSwitchWithValue("use-angle", "gl-egl")
512
513 (&dumberBPH{engine: &Engine{ctx: context.Background()}}).OnBeforeChildProcessLaunch(commandLine)
514
515 if got := commandLine.GetSwitchValue("use-angle"); got != "vulkan" {
516 t.Fatalf("use-angle = %q, want vulkan", got)
517 }
518 if got := commandLine.GetSwitchValue(chromiumEnableFeaturesSwitch); !strings.Contains(got, "AcceleratedVideoDecoder") || !strings.Contains(got, "VulkanFromANGLE") {
519 t.Fatalf("enable-features = %q, want hardware decode and Vulkan ANGLE features", got)
520 }
521 if !commandLine.HasSwitch("ignore-gpu-blocklist") {
522 t.Fatal("expected ignore-gpu-blocklist switch")
523 }
524 if !commandLine.HasSwitch("enable-zero-copy") {
525 t.Fatal("expected enable-zero-copy switch")
526 }
527 if !commandLine.HasSwitch("no-zygote") {
528 t.Fatal("expected no-zygote switch")
529 }
530}
531
532func TestDumberBPH_OnBeforeChildProcessLaunch_DisablesWebAuthnByDefault(t *testing.T) {
533 t.Setenv(cefEnableWebAuthnUnsafeEnvVar, "")
534
535 commandLine := newMutableCommandLineStub()
536 commandLine.AppendSwitchWithValue("type", "renderer")
537
538 (&dumberBPH{engine: &Engine{ctx: context.Background()}}).OnBeforeChildProcessLaunch(commandLine)
539
540 want := "WebAuth"
541 if got := commandLine.GetSwitchValue(chromiumDisableFeaturesSwitch); got != want {
542 t.Fatalf("disable-features = %q, want %q", got, want)
543 }
544 if got := commandLine.GetSwitchValue(chromiumDisableBlinkFeaturesSwitch); got != want {
545 t.Fatalf("disable-blink-features = %q, want %q", got, want)
546 }
547 if !commandLine.HasSwitch("no-zygote") {
548 t.Fatal("expected no-zygote switch to be appended")
549 }
550}