Merge pull request #305845 from abathur/resholve_0.10.5
[NixPkgs.git] / nixos / tests / lomiri.nix
blob9d6337e9977cb9674484de0f5468fda730c01e67
1 import ./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";
6 in {
7   name = "lomiri";
9   meta = {
10     maintainers = lib.teams.lomiri.members;
11   };
13   nodes.machine = { config, ... }: {
14     imports = [
15       ./common/user-account.nix
16     ];
18     users.users.${user} = {
19       inherit description password;
20     };
22     services.desktopManager.lomiri.enable = lib.mkForce true;
23     services.displayManager.defaultSession = lib.mkForce "lomiri";
25     fonts.packages = [ pkgs.inconsolata ];
27     environment = {
28       # Help with OCR
29       etc."xdg/alacritty/alacritty.yml".text = lib.generators.toYAML { } {
30         font = rec {
31           normal.family = "Inconsolata";
32           bold.family = normal.family;
33           italic.family = normal.family;
34           bold_italic.family = normal.family;
35           size = 16;
36         };
37         colors = rec {
38           primary = {
39             foreground = "0x000000";
40             background = "0xffffff";
41           };
42           normal = {
43             green = primary.foreground;
44           };
45         };
46       };
48       variables = {
49         # So we can test what content-hub is working behind the scenes
50         CONTENT_HUB_LOGGING_LEVEL = "2";
51       };
53       systemPackages = with pkgs; [
54         # For a convenient way of kicking off content-hub peer collection
55         lomiri.content-hub.examples
57         # Forcing alacritty to run as an X11 app when opened from the starter menu
58         (symlinkJoin {
59           name = "x11-${alacritty.name}";
61           paths = [ alacritty ];
63           nativeBuildInputs = [ makeWrapper ];
65           postBuild = ''
66             wrapProgram $out/bin/alacritty \
67               --set WINIT_UNIX_BACKEND x11 \
68               --set WAYLAND_DISPLAY ""
69           '';
71           inherit (alacritty) meta;
72         })
73       ];
74     };
76     # Help with OCR
77     systemd.tmpfiles.settings = let
78       white = "255, 255, 255";
79       black = "0, 0, 0";
80       colorSection = color: {
81         Color = color;
82         Bold = true;
83         Transparency = false;
84       };
85       terminalColors = pkgs.writeText "customized.colorscheme" (lib.generators.toINI {} {
86         Background = colorSection white;
87         Foreground = colorSection black;
88         Color2 = colorSection black;
89         Color2Intense = colorSection black;
90       });
91       terminalConfig = pkgs.writeText "terminal.ubports.conf" (lib.generators.toINI {} {
92         General = {
93           colorScheme = "customized";
94           fontSize = "16";
95           fontStyle = "Inconsolata";
96         };
97       });
98       confBase = "${config.users.users.${user}.home}/.config";
99       userDirArgs = {
100         mode = "0700";
101         user = user;
102         group = "users";
103       };
104     in {
105       "10-lomiri-test-setup" = {
106         "${confBase}".d = userDirArgs;
107         "${confBase}/terminal.ubports".d = userDirArgs;
108         "${confBase}/terminal.ubports/customized.colorscheme".L.argument = "${terminalColors}";
109         "${confBase}/terminal.ubports/terminal.ubports.conf".L.argument = "${terminalConfig}";
110       };
111     };
112   };
114   enableOCR = true;
116   testScript = { nodes, ... }: ''
117     def open_starter():
118         """
119         Open the starter, and ensure it's opened.
120         """
121         machine.send_key("meta_l-a")
122         # Look for any of the default apps
123         machine.wait_for_text(r"(Search|System|Settings|Morph|Browser|Terminal|Alacritty)")
125     def toggle_maximise():
126         """
127         Send the keybind to maximise the current window.
128         """
129         machine.send_key("ctrl-meta_l-up")
131         # For some reason, Lomiri in these VM tests very frequently opens the starter menu a few seconds after sending the above.
132         # Because this isn't 100% reproducible all the time, and there is no command to await when OCR doesn't pick up some text,
133         # the best we can do is send some Escape input after waiting some arbitrary time and hope that it works out fine.
134         machine.sleep(5)
135         machine.send_key("esc")
136         machine.sleep(5)
138     start_all()
139     machine.wait_for_unit("multi-user.target")
141     # Lomiri in greeter mode should work & be able to start a session
142     with subtest("lomiri greeter works"):
143         machine.wait_for_unit("display-manager.service")
144         # Start page shows current tie
145         machine.wait_for_text(r"(AM|PM)")
146         machine.screenshot("lomiri_greeter_launched")
148         # Advance to login part
149         machine.send_key("ret")
150         machine.wait_for_text("${description}")
151         machine.screenshot("lomiri_greeter_login")
153         # Login
154         machine.send_chars("${password}\n")
155         # Best way I can think of to differenciate "Lomiri in LightDM greeter mode" from "Lomiri in user shell mode"
156         machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'")
158     # The session should start, and not be stuck in i.e. a crash loop
159     with subtest("lomiri starts"):
160         # Output rendering from Lomiri has started when it starts printing performance diagnostics
161         machine.wait_for_console_text("Last frame took")
162         # Look for datetime's clock, one of the last elements to load
163         machine.wait_for_text(r"(AM|PM)")
164         machine.screenshot("lomiri_launched")
166     # Working terminal keybind is good
167     with subtest("terminal keybind works"):
168         machine.send_key("ctrl-alt-t")
169         machine.wait_for_text(r"(${user}|machine)")
170         machine.screenshot("terminal_opens")
172         # lomiri-terminal-app has a separate VM test to test its basic functionality
174         # for the LSS content-hub test to work reliably, we need to kick off peer collecting
175         machine.send_chars("content-hub-test-importer\n")
176         machine.wait_for_text(r"(/build/source|hub.cpp|handler.cpp|void|virtual|const)") # awaiting log messages from content-hub
177         machine.send_key("ctrl-c")
179         machine.send_key("alt-f4")
181     # We want the ability to launch applications
182     with subtest("starter menu works"):
183         open_starter()
184         machine.screenshot("starter_opens")
186         # Just try the terminal again, we know that it should work
187         machine.send_chars("Terminal\n")
188         machine.wait_for_text(r"(${user}|machine)")
189         machine.send_key("alt-f4")
191     # We want support for X11 apps
192     with subtest("xwayland support works"):
193         open_starter()
194         machine.send_chars("Alacritty\n")
195         machine.wait_for_text(r"(${user}|machine)")
196         machine.screenshot("alacritty_opens")
197         machine.send_key("alt-f4")
199     # LSS provides DE settings
200     with subtest("system settings open"):
201         open_starter()
202         machine.send_chars("System Settings\n")
203         machine.wait_for_text("Rotation Lock")
204         machine.screenshot("settings_open")
206         # lomiri-system-settings has a separate VM test, only test Lomiri-specific content-hub functionalities here
208         # Make fullscreen, can't navigate to Background plugin via keyboard unless window has non-phone-like aspect ratio
209         toggle_maximise()
211         # Load Background plugin
212         machine.send_key("tab")
213         machine.send_key("tab")
214         machine.send_key("tab")
215         machine.send_key("tab")
216         machine.send_key("tab")
217         machine.send_key("tab")
218         machine.send_key("ret")
219         machine.wait_for_text("Background image")
221         # Try to load custom background
222         machine.send_key("shift-tab")
223         machine.send_key("shift-tab")
224         machine.send_key("shift-tab")
225         machine.send_key("shift-tab")
226         machine.send_key("shift-tab")
227         machine.send_key("shift-tab")
228         machine.send_key("ret")
230         # Peers should be loaded
231         machine.wait_for_text("Morph") # or Gallery, but Morph is already packaged
232         machine.screenshot("settings_content-hub_peers")
234         # Sadly, it doesn't seem possible to actually select a peer and attempt a content-hub data exchange with just the keyboard
236         machine.send_key("alt-f4")
238     # Morph is how we go online
239     with subtest("morph browser works"):
240         open_starter()
241         machine.send_chars("Morph\n")
242         machine.wait_for_text(r"(Bookmarks|address|site|visited any)")
243         machine.screenshot("morph_open")
245         # morph-browser has a separate VM test, there isn't anything new we could test here
247         machine.send_key("alt-f4")
249     # The ayatana indicators are an important part of the experience, and they hold the only graphical way of exiting the session.
250     # Reaching them via the intended way requires wayland mouse control, but ydotool lacks a module for its daemon:
251     # https://github.com/NixOS/nixpkgs/issues/183659
252     # Luckily, there's a test app that also displays their contents, but it's abit inconsistent. Hopefully this is *good-enough*.
253     with subtest("ayatana indicators work"):
254         open_starter()
255         machine.send_chars("Indicators\n")
256         machine.wait_for_text(r"(Indicators|Client|List|network|datetime|session)")
257         machine.screenshot("indicators_open")
259         # Element tab order within the indicator menus is not fully deterministic
260         # Only check that the indicators are listed & their items load
262         with subtest("lomiri indicator network works"):
263             # Select indicator-network
264             machine.send_key("tab")
265             # Don't go further down, first entry
266             machine.send_key("ret")
267             machine.wait_for_text(r"(Flight|Wi-Fi)")
268             machine.screenshot("indicators_network")
270         machine.send_key("shift-tab")
271         machine.send_key("ret")
272         machine.wait_for_text(r"(Indicators|Client|List|network|datetime|session)")
274         with subtest("ayatana indicator datetime works"):
275             # Select ayatana-indicator-datetime
276             machine.send_key("tab")
277             machine.send_key("down")
278             machine.send_key("ret")
279             machine.wait_for_text("Time and Date Settings")
280             machine.screenshot("indicators_timedate")
282         machine.send_key("shift-tab")
283         machine.send_key("ret")
284         machine.wait_for_text(r"(Indicators|Client|List|network|datetime|session)")
286         with subtest("ayatana indicator session works"):
287             # Select ayatana-indicator-session
288             machine.send_key("tab")
289             machine.send_key("down")
290             machine.send_key("ret")
291             machine.wait_for_text("Log Out")
292             machine.screenshot("indicators_session")
293   '';