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