1{
2 lib,
3 pkgs,
4 firefoxPackage,
5 ...
6}:
7{
8 name = firefoxPackage.pname;
9
10 meta = with pkgs.lib.maintainers; {
11 maintainers = [ shlevy ];
12 };
13
14 nodes.machine =
15 { pkgs, ... }:
16
17 {
18 imports = [ ./common/x11.nix ];
19 environment.systemPackages = [ pkgs.xdotool ];
20
21 programs.firefox = {
22 enable = true;
23 preferences."media.autoplay.default" = 0;
24 package = firefoxPackage;
25 };
26
27 hardware.alsa = {
28 enable = true;
29 enableRecorder = true;
30 defaultDevice.playback = "pcm.recorder";
31 };
32
33 systemd.services.audio-recorder = {
34 description = "Record NixOS test audio to /tmp/record.wav";
35 script = "${pkgs.alsa-utils}/bin/arecord -Drecorder -fS16_LE -r48000 -c2 /tmp/record.wav";
36 };
37
38 };
39
40 testScript =
41 let
42 exe = lib.getExe firefoxPackage;
43 in
44 ''
45 from contextlib import contextmanager
46
47
48 @contextmanager
49 def record_audio(machine: Machine):
50 """
51 Perform actions while recording the
52 machine audio output.
53 """
54 machine.systemctl("start audio-recorder")
55 yield
56 machine.systemctl("stop audio-recorder")
57
58
59 def wait_for_sound(machine: Machine):
60 """
61 Wait until any sound has been emitted.
62 """
63 machine.wait_for_file("/tmp/record.wav")
64 while True:
65 # Get at most 2M of the recording
66 machine.execute("tail -c 2M /tmp/record.wav > /tmp/last")
67 # Get the exact size
68 size = int(machine.succeed("stat -c '%s' /tmp/last").strip())
69 # Compare it against /dev/zero using `cmp` (skipping 50B of WAVE header).
70 # If some non-NULL bytes are found it returns 1.
71 status, output = machine.execute(
72 f"cmp -i 50 -n {size - 50} /tmp/last /dev/zero 2>&1"
73 )
74 if status == 1:
75 break
76 machine.sleep(2)
77
78
79 machine.wait_for_x()
80
81 with subtest("Wait until Firefox has finished loading the Valgrind docs page"):
82 machine.execute(
83 "xterm -e '${exe} file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' >&2 &"
84 )
85 machine.wait_for_window("Valgrind")
86 machine.sleep(40)
87
88 with subtest("Check whether Firefox can play sound"):
89 with record_audio(machine):
90 machine.succeed(
91 "${exe} file://${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/phone-incoming-call.oga >&2 &"
92 )
93 wait_for_sound(machine)
94 machine.copy_from_vm("/tmp/record.wav")
95
96 with subtest("Close sound test tab"):
97 machine.execute("xdotool key ctrl+w")
98
99 with subtest("Close default browser prompt"):
100 machine.execute("xdotool key space")
101
102 with subtest("Wait until Firefox draws the developer tool panel"):
103 machine.sleep(10)
104 machine.succeed("xwininfo -root -tree | grep Valgrind")
105 machine.screenshot("screen")
106 '';
107
108}