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