Loading nixos/tests/lomiri.nix +73 −28 Original line number Diff line number Diff line Loading @@ -76,7 +76,72 @@ let }; sharedTestFunctions = '' def wait_for_text(text): from collections.abc import Callable import tempfile import subprocess # Based on terminal-emulators.nix' check_for_pink def check_for_color(color: str) -> Callable[[bool], bool]: def check_for_color_retry(final=False) -> bool: with tempfile.NamedTemporaryFile() as tmpin: machine.send_monitor_command("screendump {}".format(tmpin.name)) cmd = 'convert {} -define histogram:unique-colors=true -format "%c" histogram:info:'.format( tmpin.name ) ret = subprocess.run(cmd, shell=True, capture_output=True) if ret.returncode != 0: raise Exception( "image analysis failed with exit code {}".format(ret.returncode) ) text = ret.stdout.decode("utf-8") return color in text return check_for_color_retry def check_for_color_continued_presence(color: str) -> Callable[[bool], bool]: colorFunc: Callable[[bool], bool] = check_for_color(color) def check_for_color_continued_presence_retry(final=False) -> bool: colorPresent: bool = colorFunc(final) if final: # If it fails now, retry handles the exception raising. # Otherwise, we passed. return colorPresent else: if colorPresent: # We want retry to continue running us until the timeout, so signal failure. return False else: # Color disappeared raise Exception( "color {} has disappeared from the screen!".format(color) ) return check_for_color_continued_presence_retry def ensure_lomiri_running() -> None: """ Ensure that Lomiri has finished starting up. """ # Process runs machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # One of the last UI elements that loads is the clock. In the past, we could OCR for AM/PM to ensure it's there. That is now flaky. # The next best thing is to look for the launcher button, and ensure it stays around for awhile (DE doesn't crash). launcherColor: str = "#5277C3" with machine.nested("Waiting for the screen to have launcherColor {} on it:".format(launcherColor)): retry(check_for_color(launcherColor)) with machine.nested("Ensuring launcherColor {} stays present on the screen:".format(launcherColor)): retry(fn=check_for_color_continued_presence(launcherColor), timeout=30) machine.screenshot("lomiri_launched") def wait_for_text(text) -> None: """ Wait for on-screen text, and try to optimise retry count for slow hardware. """ Loading @@ -84,7 +149,7 @@ let machine.sleep(30) machine.wait_for_text(text) def toggle_maximise(): def toggle_maximise() -> None: """ Maximise the current window. """ Loading @@ -98,7 +163,7 @@ let machine.send_key("esc") machine.sleep(5) def mouse_click(xpos, ypos): def mouse_click(xpos, ypos) -> None: """ Move the mouse to a screen location and hit left-click. """ Loading @@ -111,7 +176,7 @@ let machine.execute("ydotool click 0xC0") machine.sleep(2) def open_starter(): def open_starter() -> None: """ Open the starter, and ensure it's opened. """ Loading Loading @@ -179,12 +244,7 @@ let # The session should start, and not be stuck in i.e. a crash loop with subtest("lomiri starts"): machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # The ayatana indicators are an important part of the experience, and they hold the only graphical way of exiting the session. # There's a test app we could use that also displays their contents, but it's abit inconsistent. Loading Loading @@ -398,12 +458,7 @@ in # The session should start, and not be stuck in i.e. a crash loop with subtest("lomiri starts"): machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # Working terminal keybind is good with subtest("terminal keybind works"): Loading Loading @@ -550,12 +605,7 @@ in # The session should start, and not be stuck in i.e. a crash loop with subtest("lomiri starts"): machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # Working terminal keybind is good with subtest("terminal keybind works"): Loading Loading @@ -716,14 +766,9 @@ in # Login machine.send_chars("${pwInput}\n") machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # And the desktop doesn't render the wallpaper anymore. Grumble grumble... # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # Lomiri in desktop mode should use the correct keymap with subtest("lomiri session keymap works"): Loading Loading
nixos/tests/lomiri.nix +73 −28 Original line number Diff line number Diff line Loading @@ -76,7 +76,72 @@ let }; sharedTestFunctions = '' def wait_for_text(text): from collections.abc import Callable import tempfile import subprocess # Based on terminal-emulators.nix' check_for_pink def check_for_color(color: str) -> Callable[[bool], bool]: def check_for_color_retry(final=False) -> bool: with tempfile.NamedTemporaryFile() as tmpin: machine.send_monitor_command("screendump {}".format(tmpin.name)) cmd = 'convert {} -define histogram:unique-colors=true -format "%c" histogram:info:'.format( tmpin.name ) ret = subprocess.run(cmd, shell=True, capture_output=True) if ret.returncode != 0: raise Exception( "image analysis failed with exit code {}".format(ret.returncode) ) text = ret.stdout.decode("utf-8") return color in text return check_for_color_retry def check_for_color_continued_presence(color: str) -> Callable[[bool], bool]: colorFunc: Callable[[bool], bool] = check_for_color(color) def check_for_color_continued_presence_retry(final=False) -> bool: colorPresent: bool = colorFunc(final) if final: # If it fails now, retry handles the exception raising. # Otherwise, we passed. return colorPresent else: if colorPresent: # We want retry to continue running us until the timeout, so signal failure. return False else: # Color disappeared raise Exception( "color {} has disappeared from the screen!".format(color) ) return check_for_color_continued_presence_retry def ensure_lomiri_running() -> None: """ Ensure that Lomiri has finished starting up. """ # Process runs machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # One of the last UI elements that loads is the clock. In the past, we could OCR for AM/PM to ensure it's there. That is now flaky. # The next best thing is to look for the launcher button, and ensure it stays around for awhile (DE doesn't crash). launcherColor: str = "#5277C3" with machine.nested("Waiting for the screen to have launcherColor {} on it:".format(launcherColor)): retry(check_for_color(launcherColor)) with machine.nested("Ensuring launcherColor {} stays present on the screen:".format(launcherColor)): retry(fn=check_for_color_continued_presence(launcherColor), timeout=30) machine.screenshot("lomiri_launched") def wait_for_text(text) -> None: """ Wait for on-screen text, and try to optimise retry count for slow hardware. """ Loading @@ -84,7 +149,7 @@ let machine.sleep(30) machine.wait_for_text(text) def toggle_maximise(): def toggle_maximise() -> None: """ Maximise the current window. """ Loading @@ -98,7 +163,7 @@ let machine.send_key("esc") machine.sleep(5) def mouse_click(xpos, ypos): def mouse_click(xpos, ypos) -> None: """ Move the mouse to a screen location and hit left-click. """ Loading @@ -111,7 +176,7 @@ let machine.execute("ydotool click 0xC0") machine.sleep(2) def open_starter(): def open_starter() -> None: """ Open the starter, and ensure it's opened. """ Loading Loading @@ -179,12 +244,7 @@ let # The session should start, and not be stuck in i.e. a crash loop with subtest("lomiri starts"): machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # The ayatana indicators are an important part of the experience, and they hold the only graphical way of exiting the session. # There's a test app we could use that also displays their contents, but it's abit inconsistent. Loading Loading @@ -398,12 +458,7 @@ in # The session should start, and not be stuck in i.e. a crash loop with subtest("lomiri starts"): machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # Working terminal keybind is good with subtest("terminal keybind works"): Loading Loading @@ -550,12 +605,7 @@ in # The session should start, and not be stuck in i.e. a crash loop with subtest("lomiri starts"): machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # Working terminal keybind is good with subtest("terminal keybind works"): Loading Loading @@ -716,14 +766,9 @@ in # Login machine.send_chars("${pwInput}\n") machine.wait_until_succeeds("pgrep -u ${user} -f 'lomiri --mode=full-shell'") # Output rendering from Lomiri has started when it starts printing performance diagnostics machine.wait_for_console_text("Last frame took") # And the desktop doesn't render the wallpaper anymore. Grumble grumble... # Look for datetime's clock, one of the last elements to load wait_for_text(r"(AM|PM)") machine.screenshot("lomiri_launched") ensure_lomiri_running() # Lomiri in desktop mode should use the correct keymap with subtest("lomiri session keymap works"): Loading