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