nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1let
2 makeTest = import ./make-test-python.nix;
3 # Just to make sure everything is the same, need it for OCR & navigating greeter
4 user = "alice";
5 description = "Alice Foobar";
6 password = "foobar";
7
8 wallpaperName = "wallpaper.jpg";
9 # In case it ever shows up in the VM, we could OCR for it instead
10 wallpaperText = "Lorem ipsum";
11
12 # tmpfiles setup to make OCRing on terminal output more reliable
13 terminalOcrTmpfilesSetup =
14 {
15 pkgs,
16 lib,
17 config,
18 }:
19 let
20 white = "255, 255, 255";
21 black = "0, 0, 0";
22 colorSection = color: {
23 Color = color;
24 Bold = true;
25 Transparency = false;
26 };
27 terminalColors = pkgs.writeText "customized.colorscheme" (
28 lib.generators.toINI { } {
29 Background = colorSection white;
30 Foreground = colorSection black;
31 Color2 = colorSection black;
32 Color2Intense = colorSection black;
33 }
34 );
35 terminalConfig = pkgs.writeText "terminal.ubports.conf" (
36 lib.generators.toINI { } {
37 General = {
38 colorScheme = "customized";
39 fontSize = "16";
40 fontStyle = "Inconsolata";
41 };
42 }
43 );
44 confBase = "${config.users.users.${user}.home}/.config";
45 userDirArgs = {
46 mode = "0700";
47 user = user;
48 group = "users";
49 };
50 in
51 {
52 "${confBase}".d = userDirArgs;
53 "${confBase}/terminal.ubports".d = userDirArgs;
54 "${confBase}/terminal.ubports/customized.colorscheme".L.argument = "${terminalColors}";
55 "${confBase}/terminal.ubports/terminal.ubports.conf".L.argument = "${terminalConfig}";
56 };
57
58 wallpaperFile =
59 pkgs:
60 pkgs.runCommand wallpaperName
61 {
62 nativeBuildInputs = with pkgs; [
63 (imagemagick.override { ghostscriptSupport = true; }) # produce OCR-able image
64 ];
65 }
66 ''
67 magick -size 640x480 canvas:white -pointsize 30 -fill black -annotate +100+100 '${wallpaperText}' $out
68 '';
69 # gsettings tool with access to wallpaper schema
70 lomiri-gsettings =
71 pkgs:
72 pkgs.stdenv.mkDerivation {
73 name = "lomiri-gsettings";
74 dontUnpack = true;
75 nativeBuildInputs = with pkgs; [
76 glib
77 wrapGAppsHook3
78 ];
79 buildInputs = with pkgs; [
80 # Not using the Lomiri-namespaced setting yet
81 # lomiri.lomiri-schemas
82 gsettings-desktop-schemas
83 ];
84 installPhase = ''
85 runHook preInstall
86 mkdir -p $out/bin
87 ln -s ${pkgs.lib.getExe' pkgs.glib "gsettings"} $out/bin/lomiri-gsettings
88 runHook postInstall
89 '';
90 };
91 setLomiriWallpaperService =
92 pkgs:
93 let
94 lomiriServices = [
95 "lomiri.service"
96 "lomiri-full-greeter.service"
97 "lomiri-full-shell.service"
98 "lomiri-greeter.service"
99 "lomiri-shell.service"
100 ];
101 in
102 rec {
103 description = "Set Lomiri wallpaper to something OCR-able";
104 wantedBy = lomiriServices;
105 before = lomiriServices;
106 serviceConfig = {
107 Type = "oneshot";
108 # Not using the Lomiri-namespaed settings yet
109 # ExecStart = "${lomiri-gsettings pkgs}/bin/lomiri-gsettings set com.lomiri.Shell background-picture-uri file://${wallpaperFile pkgs}";
110 ExecStart = "${lomiri-gsettings pkgs}/bin/lomiri-gsettings set org.gnome.desktop.background picture-uri file://${wallpaperFile pkgs}";
111 };
112 };
113
114 sharedTestFunctions = ''
115 def wait_for_text(text):
116 """
117 Wait for on-screen text, and try to optimise retry count for slow hardware.
118 """
119
120 machine.sleep(30)
121 machine.wait_for_text(text)
122
123 def toggle_maximise():
124 """
125 Maximise the current window.
126 """
127
128 machine.send_key("ctrl-meta_l-up")
129
130 # For some reason, Lomiri in these VM tests very frequently opens the starter menu a few seconds after sending the above.
131 # Because this isn't 100% reproducible all the time, and there is no command to await when OCR doesn't pick up some text,
132 # the best we can do is send some Escape input after waiting some arbitrary time and hope that it works out fine.
133 machine.sleep(5)
134 machine.send_key("esc")
135 machine.sleep(5)
136
137 def mouse_click(xpos, ypos):
138 """
139 Move the mouse to a screen location and hit left-click.
140 """
141
142 # Move
143 machine.execute(f"ydotool mousemove --absolute -- {xpos} {ypos}")
144 machine.sleep(2)
145
146 # Click (C0 - left button: down & up)
147 machine.execute("ydotool click 0xC0")
148 machine.sleep(2)
149
150 def open_starter():
151 """
152 Open the starter, and ensure it's opened.
153 """
154
155 # Using the keybind has a chance of instantly closing the menu again? Just click the button
156 mouse_click(15, 15)
157
158 '';
159
160 makeIndicatorTest =
161 {
162 name,
163 left,
164 ocr,
165 extraCheck ? null,
166
167 titleOcr,
168 }:
169
170 makeTest (
171 { pkgs, lib, ... }:
172 {
173 name = "lomiri-desktop-ayatana-indicator-${name}";
174
175 meta = {
176 maintainers = lib.teams.lomiri.members;
177 };
178
179 nodes.machine =
180 { config, ... }:
181 {
182 imports = [
183 ./common/auto.nix
184 ./common/user-account.nix
185 ];
186
187 virtualisation.memorySize = 2047;
188
189 users.users.${user} = {
190 inherit description password;
191 };
192
193 test-support.displayManager.auto = {
194 enable = true;
195 inherit user;
196 };
197
198 # To control mouse via scripting
199 programs.ydotool.enable = true;
200
201 services.desktopManager.lomiri.enable = lib.mkForce true;
202 services.displayManager.defaultSession = lib.mkForce "lomiri";
203
204 # Not setting wallpaper, as it breaks indicator OCR(?)
205 };
206
207 enableOCR = true;
208
209 testScript =
210 { nodes, ... }:
211 sharedTestFunctions
212 + ''
213 start_all()
214 machine.wait_for_unit("multi-user.target")
215
216 # The session should start, and not be stuck in i.e. a crash loop
217 with subtest("lomiri starts"):
218 machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'")
219 # Output rendering from Lomiri has started when it starts printing performance diagnostics
220 machine.wait_for_console_text("Last frame took")
221 # Look for datetime's clock, one of the last elements to load
222 wait_for_text(r"(AM|PM)")
223 machine.screenshot("lomiri_launched")
224
225 # The ayatana indicators are an important part of the experience, and they hold the only graphical way of exiting the session.
226 # There's a test app we could use that also displays their contents, but it's abit inconsistent.
227 mouse_click(735, 0) # the cog in the top-right, for the session indicator
228 wait_for_text(${titleOcr})
229 machine.screenshot("indicators_open")
230
231 # Indicator order within the menus *should* be fixed based on per-indicator order setting
232 # Session is the one we clicked, but it might not be the one we want to test right now.
233 # Go as far left as necessary.
234 ${lib.strings.replicate left "machine.send_key(\"left\")\n"}
235
236 with subtest("ayatana indicator session works"):
237 wait_for_text(r"(${lib.strings.concatStringsSep "|" ocr})")
238 machine.screenshot("indicator_${name}")
239 ''
240 + lib.optionalString (extraCheck != null) extraCheck;
241 }
242 );
243
244 makeIndicatorTests =
245 {
246 titles,
247 details,
248 }:
249 let
250 titleOcr = "r\"(${builtins.concatStringsSep "|" titles})\"";
251 in
252 builtins.listToAttrs (
253 builtins.map (
254 {
255 name,
256 left,
257 ocr,
258 extraCheck ? null,
259 }:
260 {
261 name = "desktop-ayatana-indicator-${name}";
262 value = makeIndicatorTest {
263 inherit
264 name
265 left
266 ocr
267 extraCheck
268 titleOcr
269 ;
270 };
271 }
272 ) details
273 );
274in
275{
276 greeter = makeTest (
277 { pkgs, lib, ... }:
278 {
279 name = "lomiri-greeter";
280
281 meta = {
282 maintainers = lib.teams.lomiri.members;
283 };
284
285 nodes.machine =
286 { config, ... }:
287 {
288 imports = [ ./common/user-account.nix ];
289
290 virtualisation.memorySize = 2047;
291
292 users.users.${user} = {
293 inherit description password;
294 };
295
296 services.xserver.enable = true;
297 services.xserver.windowManager.icewm.enable = true;
298 services.xserver.displayManager.lightdm = {
299 enable = true;
300 greeters.lomiri.enable = true;
301 };
302 services.displayManager.defaultSession = lib.mkForce "none+icewm";
303 };
304
305 enableOCR = true;
306
307 testScript =
308 { nodes, ... }:
309 sharedTestFunctions
310 + ''
311 start_all()
312 machine.wait_for_unit("multi-user.target")
313
314 # Lomiri in greeter mode should work & be able to start a session
315 with subtest("lomiri greeter works"):
316 machine.wait_for_unit("display-manager.service")
317 machine.wait_until_succeeds("pgrep -u lightdm -f 'lomiri --mode=greeter'")
318
319 # Start page shows current time
320 wait_for_text(r"(AM|PM)")
321 machine.screenshot("lomiri_greeter_launched")
322
323 # Advance to login part
324 machine.send_key("ret")
325 wait_for_text("${description}")
326 machine.screenshot("lomiri_greeter_login")
327
328 # Login
329 machine.send_chars("${password}\n")
330 machine.wait_for_x()
331 machine.screenshot("session_launched")
332 '';
333 }
334 );
335
336 desktop-basics = makeTest (
337 { pkgs, lib, ... }:
338 {
339 name = "lomiri-desktop-basics";
340
341 meta = {
342 maintainers = lib.teams.lomiri.members;
343 };
344
345 nodes.machine =
346 { config, ... }:
347 {
348 imports = [
349 ./common/auto.nix
350 ./common/user-account.nix
351 ];
352
353 virtualisation.memorySize = 2047;
354
355 users.users.${user} = {
356 inherit description password;
357 };
358
359 test-support.displayManager.auto = {
360 enable = true;
361 inherit user;
362 };
363
364 # To control mouse via scripting
365 programs.ydotool.enable = true;
366
367 services.desktopManager.lomiri.enable = lib.mkForce true;
368 services.displayManager.defaultSession = lib.mkForce "lomiri";
369
370 # Help with OCR
371 fonts.packages = [ pkgs.inconsolata ];
372
373 environment = {
374 # Help with OCR
375 etc."xdg/alacritty/alacritty.toml".source = (pkgs.formats.toml { }).generate "alacritty.toml" {
376 font = rec {
377 normal.family = "Inconsolata";
378 bold.family = normal.family;
379 italic.family = normal.family;
380 bold_italic.family = normal.family;
381 size = 16;
382 };
383 colors = rec {
384 primary = {
385 foreground = "0x000000";
386 background = "0xffffff";
387 };
388 normal = {
389 green = primary.foreground;
390 };
391 };
392 };
393
394 etc."${wallpaperName}".source = wallpaperFile pkgs;
395
396 systemPackages = with pkgs; [
397 # Forcing alacritty to run as an X11 app when opened from the starter menu
398 (symlinkJoin {
399 name = "x11-${alacritty.name}";
400
401 paths = [ alacritty ];
402
403 nativeBuildInputs = [ makeWrapper ];
404
405 postBuild = ''
406 wrapProgram $out/bin/alacritty \
407 --set WINIT_UNIX_BACKEND x11 \
408 --set WAYLAND_DISPLAY ""
409 '';
410
411 inherit (alacritty) meta;
412 })
413 ];
414 };
415
416 # Help with OCR
417 systemd.tmpfiles.settings = {
418 "10-lomiri-test-setup" = terminalOcrTmpfilesSetup { inherit pkgs lib config; };
419 };
420
421 systemd.user.services.set-lomiri-wallpaper = setLomiriWallpaperService pkgs;
422 };
423
424 enableOCR = true;
425
426 testScript =
427 { nodes, ... }:
428 sharedTestFunctions
429 + ''
430 start_all()
431 machine.wait_for_unit("multi-user.target")
432
433 # The session should start, and not be stuck in i.e. a crash loop
434 with subtest("lomiri starts"):
435 machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'")
436 # Output rendering from Lomiri has started when it starts printing performance diagnostics
437 machine.wait_for_console_text("Last frame took")
438 # Look for datetime's clock, one of the last elements to load
439 wait_for_text(r"(AM|PM)")
440 machine.screenshot("lomiri_launched")
441
442 # Working terminal keybind is good
443 with subtest("terminal keybind works"):
444 machine.send_key("ctrl-alt-t")
445 wait_for_text(r"(${user}|machine)")
446 machine.screenshot("terminal_opens")
447 machine.send_key("alt-f4")
448
449 # We want the ability to launch applications
450 with subtest("starter menu works"):
451 open_starter()
452 machine.screenshot("starter_opens")
453
454 # Just try the terminal again, we know that it should work
455 machine.send_chars("Terminal\n")
456 wait_for_text(r"(${user}|machine)")
457 machine.send_key("alt-f4")
458
459 # We want support for X11 apps
460 with subtest("xwayland support works"):
461 open_starter()
462 machine.send_chars("Alacritty\n")
463 wait_for_text(r"(${user}|machine)")
464 machine.screenshot("alacritty_opens")
465 machine.send_key("alt-f4")
466
467 # Morph is how we go online
468 with subtest("morph browser works"):
469 open_starter()
470 machine.send_chars("Morph\n")
471 wait_for_text(r"(Bookmarks|address|site|visited any)")
472 machine.screenshot("morph_open")
473
474 # morph-browser has a separate VM test to test its basic functionalities
475
476 machine.send_key("alt-f4")
477
478 # LSS provides DE settings
479 with subtest("system settings open"):
480 open_starter()
481 machine.send_chars("System Settings\n")
482 wait_for_text("Rotation Lock")
483 machine.screenshot("settings_open")
484
485 # lomiri-system-settings has a separate VM test to test its basic functionalities
486
487 machine.send_key("alt-f4")
488 '';
489 }
490 );
491
492 desktop-appinteractions = makeTest (
493 { pkgs, lib, ... }:
494 {
495 name = "lomiri-desktop-appinteractions";
496
497 meta = {
498 maintainers = lib.teams.lomiri.members;
499 };
500
501 nodes.machine =
502 { config, ... }:
503 {
504 imports = [
505 ./common/auto.nix
506 ./common/user-account.nix
507 ];
508
509 virtualisation.memorySize = 2047;
510
511 users.users.${user} = {
512 inherit description password;
513 # polkit agent test
514 extraGroups = [ "wheel" ];
515 };
516
517 test-support.displayManager.auto = {
518 enable = true;
519 inherit user;
520 };
521
522 # To control mouse via scripting
523 programs.ydotool.enable = true;
524
525 services.desktopManager.lomiri.enable = lib.mkForce true;
526 services.displayManager.defaultSession = lib.mkForce "lomiri";
527
528 # Help with OCR
529 fonts.packages = [ pkgs.inconsolata ];
530
531 environment = {
532 # Help with OCR
533 etc."xdg/alacritty/alacritty.yml".text = lib.generators.toYAML { } {
534 font = rec {
535 normal.family = "Inconsolata";
536 bold.family = normal.family;
537 italic.family = normal.family;
538 bold_italic.family = normal.family;
539 size = 16;
540 };
541 colors = rec {
542 primary = {
543 foreground = "0x000000";
544 background = "0xffffff";
545 };
546 normal = {
547 green = primary.foreground;
548 };
549 };
550 };
551
552 etc."${wallpaperName}".source = wallpaperFile pkgs;
553
554 variables = {
555 # So we can test what lomiri-content-hub is working behind the scenes
556 LOMIRI_CONTENT_HUB_LOGGING_LEVEL = "2";
557 };
558
559 systemPackages = with pkgs; [
560 # For a convenient way of kicking off lomiri-content-hub peer collection
561 lomiri.lomiri-content-hub.examples
562 ];
563 };
564
565 # Help with OCR
566 systemd.tmpfiles.settings = {
567 "10-lomiri-test-setup" = terminalOcrTmpfilesSetup { inherit pkgs lib config; };
568 };
569
570 systemd.user.services.set-lomiri-wallpaper = setLomiriWallpaperService pkgs;
571 };
572
573 enableOCR = true;
574
575 testScript =
576 { nodes, ... }:
577 sharedTestFunctions
578 + ''
579 start_all()
580 machine.wait_for_unit("multi-user.target")
581
582 # The session should start, and not be stuck in i.e. a crash loop
583 with subtest("lomiri starts"):
584 machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'")
585 # Output rendering from Lomiri has started when it starts printing performance diagnostics
586 machine.wait_for_console_text("Last frame took")
587 # Look for datetime's clock, one of the last elements to load
588 wait_for_text(r"(AM|PM)")
589 machine.screenshot("lomiri_launched")
590
591 # Working terminal keybind is good
592 with subtest("terminal keybind works"):
593 machine.send_key("ctrl-alt-t")
594 wait_for_text(r"(${user}|machine)")
595 machine.screenshot("terminal_opens")
596
597 # for the LSS lomiri-content-hub test to work reliably, we need to kick off peer collecting
598 machine.send_chars("lomiri-content-hub-test-importer\n")
599 wait_for_text(r"(/build/source|hub.cpp|handler.cpp|void|virtual|const)") # awaiting log messages from lomiri-content-hub
600 machine.send_key("ctrl-c")
601
602 # Doing this here, since we need an in-session shell & separately starting a terminal again wastes time
603 with subtest("polkit agent works"):
604 machine.send_chars("pkexec touch /tmp/polkit-test\n")
605 # There's an authentication notification here that gains focus, but we struggle with OCRing it
606 # Just hope that it's up after a short wait
607 machine.sleep(10)
608 machine.screenshot("polkit_agent")
609 machine.send_chars("${password}")
610 machine.sleep(2) # Hopefully enough delay to make sure all the password characters have been registered? Maybe just placebo
611 machine.send_chars("\n")
612 machine.wait_for_file("/tmp/polkit-test", 10)
613
614 machine.send_key("alt-f4")
615
616 # LSS provides DE settings
617 with subtest("system settings open"):
618 open_starter()
619 machine.send_chars("System Settings\n")
620 wait_for_text("Rotation Lock")
621 machine.screenshot("settings_open")
622
623 # lomiri-system-settings has a separate VM test, only test Lomiri-specific lomiri-content-hub functionalities here
624
625 # Make fullscreen, can't navigate to Background plugin via keyboard unless window has non-phone-like aspect ratio
626 toggle_maximise()
627
628 # Load Background plugin
629 machine.send_key("tab")
630 machine.send_key("tab")
631 machine.send_key("tab")
632 machine.send_key("tab")
633 machine.send_key("tab")
634 machine.send_key("tab")
635 machine.send_key("ret")
636 wait_for_text("Background image")
637
638 # Try to load custom background
639 machine.send_key("shift-tab")
640 machine.send_key("shift-tab")
641 machine.send_key("shift-tab")
642 machine.send_key("shift-tab")
643 machine.send_key("shift-tab")
644 machine.send_key("shift-tab")
645 machine.send_key("ret")
646
647 # Peers should be loaded
648 wait_for_text("Morph") # or Gallery, but Morph is already packaged
649 machine.screenshot("settings_lomiri-content-hub_peers")
650
651 # Select Morph as content source
652 mouse_click(340, 80)
653
654 # Expect Morph to be brought into the foreground, with its Downloads page open
655 wait_for_text("No downloads")
656
657 # If lomiri-content-hub encounters a problem, it may have crashed the original application issuing the request.
658 # Check that it's still alive
659 machine.succeed("pgrep -u ${user} -f lomiri-system-settings")
660
661 machine.screenshot("lomiri-content-hub_exchange")
662
663 # Testing any more would require more applications & setup, the fact that it's already being attempted is a good sign
664 machine.send_key("esc")
665
666 machine.sleep(2) # sleep a tiny bit so morph can close & the focus can return to LSS
667 machine.send_key("alt-f4")
668 '';
669 }
670 );
671
672 keymap =
673 let
674 pwInput = "qwerty";
675 pwOutput = "qwertz";
676 in
677 makeTest (
678 { pkgs, lib, ... }:
679 {
680 name = "lomiri-keymap";
681
682 meta = {
683 maintainers = lib.teams.lomiri.members;
684 };
685
686 nodes.machine =
687 { config, ... }:
688 {
689 imports = [ ./common/user-account.nix ];
690
691 virtualisation.memorySize = 2047;
692
693 users.users.${user} = {
694 inherit description;
695 password = lib.mkForce pwOutput;
696 };
697
698 services.desktopManager.lomiri.enable = lib.mkForce true;
699 services.displayManager.defaultSession = lib.mkForce "lomiri";
700
701 # Help with OCR
702 fonts.packages = [ pkgs.inconsolata ];
703
704 services.xserver.xkb.layout = lib.strings.concatStringsSep "," [
705 # Start with a non-QWERTY keymap to test keymap patch
706 "de"
707 # Then a QWERTY one to test switching
708 "us"
709 ];
710
711 environment.etc."${wallpaperName}".source = wallpaperFile pkgs;
712
713 systemd.user.services.set-lomiri-wallpaper = setLomiriWallpaperService pkgs;
714
715 # Help with OCR
716 systemd.tmpfiles.settings = {
717 "10-lomiri-test-setup" = terminalOcrTmpfilesSetup { inherit pkgs lib config; };
718 };
719 };
720
721 enableOCR = true;
722
723 testScript =
724 { nodes, ... }:
725 sharedTestFunctions
726 + ''
727 start_all()
728 machine.wait_for_unit("multi-user.target")
729
730 # Lomiri in greeter mode should use the correct keymap
731 with subtest("lomiri greeter keymap works"):
732 machine.wait_for_unit("display-manager.service")
733 machine.wait_until_succeeds("pgrep -u lightdm -f 'lomiri --mode=greeter'")
734
735 # Start page shows current time
736 wait_for_text(r"(AM|PM)")
737 machine.screenshot("lomiri_greeter_launched")
738
739 # Advance to login part
740 machine.send_key("ret")
741 wait_for_text("${description}")
742 machine.screenshot("lomiri_greeter_login")
743
744 # Login
745 machine.send_chars("${pwInput}\n")
746 machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'")
747
748 # Output rendering from Lomiri has started when it starts printing performance diagnostics
749 machine.wait_for_console_text("Last frame took")
750 # Look for datetime's clock, one of the last elements to load
751 wait_for_text(r"(AM|PM)")
752 machine.screenshot("lomiri_launched")
753
754 # Lomiri in desktop mode should use the correct keymap
755 with subtest("lomiri session keymap works"):
756 machine.send_key("ctrl-alt-t")
757 wait_for_text(r"(${user}|machine)")
758 machine.screenshot("terminal_opens")
759
760 machine.send_chars("touch ${pwInput}\n")
761 machine.wait_for_file("/home/alice/${pwOutput}", 90)
762
763 # Issues with this keybind: input leaks to focused surface, may open launcher
764 # Don't have the keyboard indicator to handle this better
765 machine.send_key("meta_l-spc")
766 machine.wait_for_console_text('SET KEYMAP "us"')
767
768 # Handle keybind fallout
769 machine.sleep(10) # wait for everything to settle
770 machine.send_key("esc") # close launcher in case it was opened
771 machine.sleep(2) # wait for animation to finish
772 # Make sure input leaks are gone
773 machine.send_key("backspace")
774 machine.send_key("backspace")
775 machine.send_key("backspace")
776 machine.send_key("backspace")
777 machine.send_key("backspace")
778 machine.send_key("backspace")
779 machine.send_key("backspace")
780 machine.send_key("backspace")
781 machine.send_key("backspace")
782 machine.send_key("backspace")
783
784 machine.send_chars("touch ${pwInput}\n")
785 machine.wait_for_file("/home/alice/${pwInput}", 90)
786
787 machine.send_key("alt-f4")
788 '';
789 }
790 );
791}
792// makeIndicatorTests {
793 titles = [
794 "Notifications" # messages
795 "Rotation" # display
796 "Battery" # power
797 "Sound" # sound
798 "Time" # datetime
799 "Date" # datetime
800 "System" # session
801 ];
802 details = [
803 # messages normally has no contents
804 ({
805 name = "display";
806 left = 6;
807 ocr = [ "Lock" ];
808 })
809 ({
810 name = "bluetooth";
811 left = 5;
812 ocr = [ "Bluetooth" ];
813 })
814 ({
815 name = "network";
816 left = 4;
817 ocr = [
818 "Flight"
819 "Wi-Fi"
820 ];
821 })
822 ({
823 name = "sound";
824 left = 3;
825 ocr = [
826 "Silent"
827 "Volume"
828 ];
829 })
830 ({
831 name = "power";
832 left = 2;
833 ocr = [
834 "Charge"
835 "Battery"
836 ];
837 })
838 ({
839 name = "datetime";
840 left = 1;
841 ocr = [
842 "Time"
843 "Date"
844 ];
845 })
846 ({
847 name = "session";
848 left = 0;
849 ocr = [ "Log Out" ];
850 extraCheck = ''
851 # We should be able to log out and return to the greeter
852 mouse_click(600, 280) # "Log Out"
853 mouse_click(340, 220) # confirm logout
854 machine.wait_until_fails("pgrep -u ${user} -f 'lomiri --mode=full-shell'")
855 '';
856 })
857 ];
858}