at 24.11-pre 12 kB view raw
1import ./make-test-python.nix ({ pkgs, lib, ... }: let 2 # Just to make sure everything is the same, need it for OCR & navigating greeter 3 user = "alice"; 4 description = "Alice Foobar"; 5 password = "foobar"; 6in { 7 name = "lomiri"; 8 9 meta = { 10 maintainers = lib.teams.lomiri.members; 11 }; 12 13 nodes.machine = { config, ... }: { 14 imports = [ 15 ./common/user-account.nix 16 ]; 17 18 users.users.${user} = { 19 inherit description password; 20 }; 21 22 # To control mouse via scripting 23 programs.ydotool.enable = true; 24 25 services.desktopManager.lomiri.enable = lib.mkForce true; 26 services.displayManager.defaultSession = lib.mkForce "lomiri"; 27 28 # Help with OCR 29 fonts.packages = [ pkgs.inconsolata ]; 30 31 environment = { 32 # Help with OCR 33 etc."xdg/alacritty/alacritty.yml".text = lib.generators.toYAML { } { 34 font = rec { 35 normal.family = "Inconsolata"; 36 bold.family = normal.family; 37 italic.family = normal.family; 38 bold_italic.family = normal.family; 39 size = 16; 40 }; 41 colors = rec { 42 primary = { 43 foreground = "0x000000"; 44 background = "0xffffff"; 45 }; 46 normal = { 47 green = primary.foreground; 48 }; 49 }; 50 }; 51 52 variables = { 53 # So we can test what content-hub is working behind the scenes 54 CONTENT_HUB_LOGGING_LEVEL = "2"; 55 }; 56 57 systemPackages = with pkgs; [ 58 # For a convenient way of kicking off content-hub peer collection 59 lomiri.content-hub.examples 60 61 # Forcing alacritty to run as an X11 app when opened from the starter menu 62 (symlinkJoin { 63 name = "x11-${alacritty.name}"; 64 65 paths = [ alacritty ]; 66 67 nativeBuildInputs = [ makeWrapper ]; 68 69 postBuild = '' 70 wrapProgram $out/bin/alacritty \ 71 --set WINIT_UNIX_BACKEND x11 \ 72 --set WAYLAND_DISPLAY "" 73 ''; 74 75 inherit (alacritty) meta; 76 }) 77 ]; 78 }; 79 80 # Help with OCR 81 systemd.tmpfiles.settings = let 82 white = "255, 255, 255"; 83 black = "0, 0, 0"; 84 colorSection = color: { 85 Color = color; 86 Bold = true; 87 Transparency = false; 88 }; 89 terminalColors = pkgs.writeText "customized.colorscheme" (lib.generators.toINI {} { 90 Background = colorSection white; 91 Foreground = colorSection black; 92 Color2 = colorSection black; 93 Color2Intense = colorSection black; 94 }); 95 terminalConfig = pkgs.writeText "terminal.ubports.conf" (lib.generators.toINI {} { 96 General = { 97 colorScheme = "customized"; 98 fontSize = "16"; 99 fontStyle = "Inconsolata"; 100 }; 101 }); 102 confBase = "${config.users.users.${user}.home}/.config"; 103 userDirArgs = { 104 mode = "0700"; 105 user = user; 106 group = "users"; 107 }; 108 in { 109 "10-lomiri-test-setup" = { 110 "${confBase}".d = userDirArgs; 111 "${confBase}/terminal.ubports".d = userDirArgs; 112 "${confBase}/terminal.ubports/customized.colorscheme".L.argument = "${terminalColors}"; 113 "${confBase}/terminal.ubports/terminal.ubports.conf".L.argument = "${terminalConfig}"; 114 }; 115 }; 116 }; 117 118 enableOCR = true; 119 120 testScript = { nodes, ... }: '' 121 def toggle_maximise(): 122 """ 123 Maximise the current window. 124 """ 125 machine.send_key("ctrl-meta_l-up") 126 127 # For some reason, Lomiri in these VM tests very frequently opens the starter menu a few seconds after sending the above. 128 # Because this isn't 100% reproducible all the time, and there is no command to await when OCR doesn't pick up some text, 129 # the best we can do is send some Escape input after waiting some arbitrary time and hope that it works out fine. 130 machine.sleep(5) 131 machine.send_key("esc") 132 machine.sleep(5) 133 134 def mouse_click(xpos, ypos): 135 """ 136 Move the mouse to a screen location and hit left-click. 137 """ 138 139 # Need to reset to top-left, --absolute doesn't work? 140 machine.execute("ydotool mousemove -- -10000 -10000") 141 machine.sleep(2) 142 143 # Move 144 machine.execute(f"ydotool mousemove -- {xpos} {ypos}") 145 machine.sleep(2) 146 147 # Click (C0 - left button: down & up) 148 machine.execute("ydotool click 0xC0") 149 machine.sleep(2) 150 151 def open_starter(): 152 """ 153 Open the starter, and ensure it's opened. 154 """ 155 156 # Using the keybind has a chance of instantly closing the menu again? Just click the button 157 mouse_click(20, 30) 158 159 # Look for Search box & GUI-less content-hub examples, highest chances of avoiding false positives 160 machine.wait_for_text(r"(Search|Export|Import|Share)") 161 162 start_all() 163 machine.wait_for_unit("multi-user.target") 164 165 # Lomiri in greeter mode should work & be able to start a session 166 with subtest("lomiri greeter works"): 167 machine.wait_for_unit("display-manager.service") 168 machine.wait_until_succeeds("pgrep -u lightdm -f 'lomiri --mode=greeter'") 169 170 # Start page shows current time 171 machine.wait_for_text(r"(AM|PM)") 172 machine.screenshot("lomiri_greeter_launched") 173 174 # Advance to login part 175 machine.send_key("ret") 176 machine.wait_for_text("${description}") 177 machine.screenshot("lomiri_greeter_login") 178 179 # Login 180 machine.send_chars("${password}\n") 181 machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") 182 183 # The session should start, and not be stuck in i.e. a crash loop 184 with subtest("lomiri starts"): 185 # Output rendering from Lomiri has started when it starts printing performance diagnostics 186 machine.wait_for_console_text("Last frame took") 187 # Look for datetime's clock, one of the last elements to load 188 machine.wait_for_text(r"(AM|PM)") 189 machine.screenshot("lomiri_launched") 190 191 # Working terminal keybind is good 192 with subtest("terminal keybind works"): 193 machine.send_key("ctrl-alt-t") 194 machine.wait_for_text(r"(${user}|machine)") 195 machine.screenshot("terminal_opens") 196 197 # lomiri-terminal-app has a separate VM test to test its basic functionality 198 199 # for the LSS content-hub test to work reliably, we need to kick off peer collecting 200 machine.send_chars("content-hub-test-importer\n") 201 machine.wait_for_text(r"(/build/source|hub.cpp|handler.cpp|void|virtual|const)") # awaiting log messages from content-hub 202 machine.send_key("ctrl-c") 203 204 machine.send_key("alt-f4") 205 206 # We want the ability to launch applications 207 with subtest("starter menu works"): 208 open_starter() 209 machine.screenshot("starter_opens") 210 211 # Just try the terminal again, we know that it should work 212 machine.send_chars("Terminal\n") 213 machine.wait_for_text(r"(${user}|machine)") 214 machine.send_key("alt-f4") 215 216 # We want support for X11 apps 217 with subtest("xwayland support works"): 218 open_starter() 219 machine.send_chars("Alacritty\n") 220 machine.wait_for_text(r"(${user}|machine)") 221 machine.screenshot("alacritty_opens") 222 machine.send_key("alt-f4") 223 224 # Morph is how we go online 225 with subtest("morph browser works"): 226 open_starter() 227 machine.send_chars("Morph\n") 228 machine.wait_for_text(r"(Bookmarks|address|site|visited any)") 229 machine.screenshot("morph_open") 230 231 # morph-browser has a separate VM test, there isn't anything new we could test here 232 233 # Keep it running, we're using it to check content-hub communication from LSS 234 235 # LSS provides DE settings 236 with subtest("system settings open"): 237 open_starter() 238 machine.send_chars("System Settings\n") 239 machine.wait_for_text("Rotation Lock") 240 machine.screenshot("settings_open") 241 242 # lomiri-system-settings has a separate VM test, only test Lomiri-specific content-hub functionalities here 243 244 # Make fullscreen, can't navigate to Background plugin via keyboard unless window has non-phone-like aspect ratio 245 toggle_maximise() 246 247 # Load Background plugin 248 machine.send_key("tab") 249 machine.send_key("tab") 250 machine.send_key("tab") 251 machine.send_key("tab") 252 machine.send_key("tab") 253 machine.send_key("tab") 254 machine.send_key("ret") 255 machine.wait_for_text("Background image") 256 257 # Try to load custom background 258 machine.send_key("shift-tab") 259 machine.send_key("shift-tab") 260 machine.send_key("shift-tab") 261 machine.send_key("shift-tab") 262 machine.send_key("shift-tab") 263 machine.send_key("shift-tab") 264 machine.send_key("ret") 265 266 # Peers should be loaded 267 machine.wait_for_text("Morph") # or Gallery, but Morph is already packaged 268 machine.screenshot("settings_content-hub_peers") 269 270 # Select Morph as content source 271 mouse_click(300, 100) 272 273 # Expect Morph to be brought into the foreground, with its Downloads page open 274 machine.wait_for_text("No downloads") 275 276 # If content-hub encounters a problem, it may have crashed the original application issuing the request. 277 # Check that it's still alive 278 machine.succeed("pgrep -u ${user} -f lomiri-system-settings") 279 280 machine.screenshot("content-hub_exchange") 281 282 # Testing any more would require more applications & setup, the fact that it's already being attempted is a good sign 283 machine.send_key("esc") 284 285 machine.send_key("alt-f4") # LSS 286 machine.sleep(2) # focus is slow to switch to second window, closing it *really* helps with OCR afterwards 287 machine.send_key("alt-f4") # Morph 288 289 # The ayatana indicators are an important part of the experience, and they hold the only graphical way of exiting the session. 290 # There's a test app we could use that also displays their contents, but it's abit inconsistent. 291 with subtest("ayatana indicators work"): 292 mouse_click(735, 0) # the cog in the top-right, for the session indicator 293 machine.wait_for_text(r"(Notifications|Battery|Time|Date|System)") 294 machine.screenshot("indicators_open") 295 296 # Indicator order within the menus *should* be fixed based on per-indicator order setting 297 # Session is the one we clicked, but the last we should test (logout). Go as far left as we can test. 298 machine.send_key("left") 299 machine.send_key("left") 300 machine.send_key("left") 301 # Notifications are usually empty, nothing to check there 302 303 with subtest("lomiri indicator network works"): 304 # We start on this, don't go right 305 machine.wait_for_text(r"(Flight|Wi-Fi)") 306 machine.screenshot("indicators_network") 307 308 with subtest("ayatana indicator power works"): 309 machine.send_key("right") 310 machine.wait_for_text(r"(Charge|Battery settings)") 311 machine.screenshot("indicators_power") 312 313 with subtest("ayatana indicator datetime works"): 314 machine.send_key("right") 315 machine.wait_for_text("Time and Date Settings") 316 machine.screenshot("indicators_timedate") 317 318 with subtest("ayatana indicator session works"): 319 machine.send_key("right") 320 machine.wait_for_text("Log Out") 321 machine.screenshot("indicators_session") 322 323 # We should be able to log out and return to the greeter 324 mouse_click(720, 280) # "Log Out" 325 mouse_click(400, 240) # confirm logout 326 machine.wait_until_fails("pgrep -u ${user} -f 'lomiri --mode=full-shell'") 327 machine.wait_until_succeeds("pgrep -u lightdm -f 'lomiri --mode=greeter'") 328 ''; 329})