1{ system ? builtins.currentSystem
2, config ? {}
3, pkgs ? import ../.. { inherit system config; }
4, channelMap ? { # Maps "channels" to packages
5 stable = pkgs.chromium;
6 beta = pkgs.chromiumBeta;
7 dev = pkgs.chromiumDev;
8 ungoogled = pkgs.ungoogled-chromium;
9 chrome-stable = pkgs.google-chrome;
10 chrome-beta = pkgs.google-chrome-beta;
11 chrome-dev = pkgs.google-chrome-dev;
12 }
13}:
14
15with import ../lib/testing-python.nix { inherit system pkgs; };
16with pkgs.lib;
17
18mapAttrs (channel: chromiumPkg: makeTest rec {
19 name = "chromium-${channel}";
20 meta = {
21 maintainers = with maintainers; [ aszlig primeos ];
22 # https://github.com/NixOS/hydra/issues/591#issuecomment-435125621
23 inherit (chromiumPkg.meta) timeout;
24 };
25
26 enableOCR = true;
27
28 user = "alice";
29
30 machine.imports = [ ./common/user-account.nix ./common/x11.nix ];
31 machine.virtualisation.memorySize = 2047;
32 machine.test-support.displayManager.auto.user = user;
33 machine.environment.systemPackages = [ chromiumPkg ];
34
35 startupHTML = pkgs.writeText "chromium-startup.html" ''
36 <!DOCTYPE html>
37 <html>
38 <head>
39 <meta charset="UTF-8">
40 <title>Chromium startup notifier</title>
41 </head>
42 <body onload="javascript:document.title='startup done'">
43 <img src="file://${pkgs.fetchurl {
44 url = "https://nixos.org/logo/nixos-hex.svg";
45 sha256 = "07ymq6nw8kc22m7kzxjxldhiq8gzmc7f45kq2bvhbdm0w5s112s4";
46 }}" />
47 </body>
48 </html>
49 '';
50
51 testScript = let
52 xdo = name: text: let
53 xdoScript = pkgs.writeText "${name}.xdo" text;
54 in "${pkgs.xdotool}/bin/xdotool ${xdoScript}";
55 in ''
56 import shlex
57 import re
58 from contextlib import contextmanager
59
60
61 # Run as user alice
62 def ru(cmd):
63 return "su - ${user} -c " + shlex.quote(cmd)
64
65
66 def get_browser_binary():
67 """Returns the name of the browser binary."""
68 pname = "${getName chromiumPkg.name}"
69 if pname.find("chromium") != -1:
70 return "chromium" # Same name for all channels and ungoogled-chromium
71 if pname == "google-chrome":
72 return "google-chrome-stable"
73 if pname == "google-chrome-dev":
74 return "google-chrome-unstable"
75 # For google-chrome-beta and as fallback:
76 return pname
77
78
79 def create_new_win():
80 """Creates a new Chromium window."""
81 with machine.nested("Creating a new Chromium window"):
82 machine.wait_until_succeeds(
83 ru(
84 "${xdo "create_new_win-select_main_window" ''
85 search --onlyvisible --name "startup done"
86 windowfocus --sync
87 windowactivate --sync
88 ''}"
89 )
90 )
91 machine.send_key("ctrl-n")
92 # Wait until the new window appears:
93 machine.wait_until_succeeds(
94 ru(
95 "${xdo "create_new_win-wait_for_window" ''
96 search --onlyvisible --name "New Tab"
97 windowfocus --sync
98 windowactivate --sync
99 ''}"
100 )
101 )
102
103
104 def close_new_tab_win():
105 """Closes the Chromium window with the title "New Tab"."""
106 machine.wait_until_succeeds(
107 ru(
108 "${xdo "close_new_tab_win-select_main_window" ''
109 search --onlyvisible --name "New Tab"
110 windowfocus --sync
111 windowactivate --sync
112 ''}"
113 )
114 )
115 machine.send_key("ctrl-w")
116 # Wait until the closed window disappears:
117 machine.wait_until_fails(
118 ru(
119 "${xdo "close_new_tab_win-wait_for_close" ''
120 search --onlyvisible --name "New Tab"
121 ''}"
122 )
123 )
124
125
126 @contextmanager
127 def test_new_win(description):
128 create_new_win()
129 with machine.nested(description):
130 yield
131 # Close the newly created window:
132 machine.send_key("ctrl-w")
133
134
135 machine.wait_for_x()
136
137 url = "file://${startupHTML}"
138 machine.succeed(ru(f'ulimit -c unlimited; "{get_browser_binary()}" "{url}" & disown'))
139
140 if get_browser_binary().startswith("google-chrome"):
141 # Need to click away the first window:
142 machine.wait_for_text("Make Google Chrome the default browser")
143 machine.screenshot("google_chrome_default_browser_prompt")
144 machine.send_key("ret")
145
146 machine.wait_for_text("startup done")
147 machine.wait_until_succeeds(
148 ru(
149 "${xdo "check-startup" ''
150 search --sync --onlyvisible --name "startup done"
151 # close first start help popup
152 key -delay 1000 Escape
153 windowfocus --sync
154 windowactivate --sync
155 ''}"
156 )
157 )
158
159 create_new_win()
160 # Optional: Wait for the new tab page to fully load before taking the screenshot:
161 machine.wait_for_text("Web Store")
162 machine.screenshot("empty_windows")
163 close_new_tab_win()
164
165 machine.screenshot("startup_done")
166
167 with test_new_win("check sandbox"):
168 machine.succeed(
169 ru(
170 "${xdo "type-url" ''
171 search --sync --onlyvisible --name "New Tab"
172 windowfocus --sync
173 type --delay 1000 "chrome://sandbox"
174 ''}"
175 )
176 )
177
178 machine.succeed(
179 ru(
180 "${xdo "submit-url" ''
181 search --sync --onlyvisible --name "New Tab"
182 windowfocus --sync
183 key --delay 1000 Return
184 ''}"
185 )
186 )
187
188 machine.screenshot("sandbox_info")
189
190 machine.succeed(
191 ru(
192 "${xdo "find-window" ''
193 search --sync --onlyvisible --name "Sandbox Status"
194 windowfocus --sync
195 ''}"
196 )
197 )
198 machine.succeed(
199 ru(
200 "${xdo "copy-sandbox-info" ''
201 key --delay 1000 Ctrl+a Ctrl+c
202 ''}"
203 )
204 )
205
206 clipboard = machine.succeed(
207 ru("${pkgs.xclip}/bin/xclip -o")
208 )
209
210 filters = [
211 "layer 1 sandbox.*namespace",
212 "pid namespaces.*yes",
213 "network namespaces.*yes",
214 "seccomp.*sandbox.*yes",
215 "you are adequately sandboxed",
216 ]
217 if not all(
218 re.search(filter, clipboard, flags=re.DOTALL | re.IGNORECASE)
219 for filter in filters
220 ):
221 assert False, f"sandbox not working properly: {clipboard}"
222
223 machine.sleep(1)
224 machine.succeed(
225 ru(
226 "${xdo "find-window-after-copy" ''
227 search --onlyvisible --name "Sandbox Status"
228 ''}"
229 )
230 )
231
232 clipboard = machine.succeed(
233 ru(
234 "echo void | ${pkgs.xclip}/bin/xclip -i"
235 )
236 )
237 machine.succeed(
238 ru(
239 "${xdo "copy-sandbox-info" ''
240 key --delay 1000 Ctrl+a Ctrl+c
241 ''}"
242 )
243 )
244
245 clipboard = machine.succeed(
246 ru("${pkgs.xclip}/bin/xclip -o")
247 )
248 if not all(
249 re.search(filter, clipboard, flags=re.DOTALL | re.IGNORECASE)
250 for filter in filters
251 ):
252 assert False, f"copying twice in a row does not work properly: {clipboard}"
253
254 machine.screenshot("after_copy_from_chromium")
255
256 machine.shutdown()
257 '';
258}) channelMap