1package app
2
3import (
4 "context"
5 "io"
6 "os"
7 "os/exec"
8 "path/filepath"
9 "testing"
10 "time"
11
12 "github.com/stretchr/testify/require"
13
14 "github.com/bnema/nefercap/internal/adapters/control"
15 "github.com/bnema/nefercap/internal/adapters/wayland"
16 "github.com/bnema/nefercap/internal/adapters/wayland/testserver"
17 "github.com/bnema/nefercap/internal/ports"
18)
19
20// Without NeferWL's extension recording shows no HUD, runs against a real
21// (in-process) compositor and is stopped through the control socket, as
22// `nefercap stop` or the shortcut do.
23func TestRecordWithoutHUDStopsViaControlSocket(t *testing.T) {
24 if _, err := exec.LookPath("ffmpeg"); err != nil {
25 t.Skip("ffmpeg unavailable")
26 }
27 runtime := filepath.Join(t.TempDir(), "runtime")
28 require.NoError(t, os.Mkdir(runtime, 0o700))
29 t.Setenv("XDG_RUNTIME_DIR", runtime)
30
31 ctx := context.Background()
32 srv := testserver.Start(t, testserver.Config{
33 Outputs: []testserver.OutputSpec{{Name: "TEST-1", Width: 64, Height: 48, Scale: 1}},
34 })
35 source, err := wayland.New(ctx, srv.Path)
36 require.NoError(t, err)
37 defer source.Close()
38 require.False(t, source.Capabilities().Exclusion)
39 outputs, err := source.Outputs(ctx)
40 require.NoError(t, err)
41
42 path := filepath.Join(t.TempDir(), "clip.mp4")
43 sel := ports.Selection{
44 Mode: ports.Record, Target: ports.Target{OutputID: outputs[0].ID}, Path: path,
45 Video: ports.VideoSettings{FPS: 30},
46 }
47 type result struct {
48 outcome recordingOutcome
49 err error
50 }
51 done := make(chan result, 1)
52 go func() {
53 o, err := recordInteractive(ctx, io.Discard, source, outputs, sel)
54 done <- result{o, err}
55 }()
56 require.Eventually(t, func() bool {
57 active, err := control.Query(ctx)
58 return err == nil && active
59 }, 5*time.Second, 10*time.Millisecond, "the recording listens on the control socket")
60 time.Sleep(200 * time.Millisecond) // a few frames
61 stopped, err := control.Stop(ctx)
62 require.NoError(t, err)
63 require.True(t, stopped)
64
65 select {
66 case r := <-done:
67 require.NoError(t, r.err, "a user stop is success")
68 require.True(t, r.outcome.Saved)
69 case <-time.After(15 * time.Second):
70 t.Fatal("recording did not stop")
71 }
72 info, err := os.Stat(path)
73 require.NoError(t, err)
74 require.NotZero(t, info.Size())
75}