Source code for fortrace.utility.desktop_environments.Linux.gnome

from time import sleep

import libvirt

from fortrace.core.qemu_monitor import QEMUMonitorSession
from fortrace.utility.applications.application import (
    ApplicationEvent,
    ApplicationType,
    GenericApplication,
)
from fortrace.utility.applications.application_factory import get_application
from fortrace.utility.desktop_environments.desktop_environment import (
    DesktopEnvironment,
    DesktopEnvironmentType,
    OSType,
)


[docs] class GNOME(DesktopEnvironment): """Explicit class to interact with GNOME desktop environments.""" def __init__(self, qemu_monitor_session: QEMUMonitorSession): super().__init__( OSType.LINUX, DesktopEnvironmentType.GNOME, qemu_monitor_session )
[docs] def open_application( self, application_type: ApplicationType, application_name: str, **kwargs ) -> GenericApplication: """Open and focus a new application on the GUI with the possibility to pass down further arguments. Args: application_type: type of application (needed for application factory) application_name: the name of the application to open (capitalization matters!) *args: pass further arguments to the opening process, if necessary Returns: an application object for further interaction """ # command window in ubuntu is somewhat broken and opens only certain applications # thus we use activities window which will also set the focus on the opened application self._qs.send_key_combination("meta_l") sleep(0.5) # wait for prompt to show up self._qs.send_text(application_name) sleep(1) # necessary so keystroke is not omitted # if the same application is already open, GNOME will focus it when not hitting ctrl-ret if self.is_application_open(application_name): self._qs.send_key_combination("ctrl-ret") else: self._qs.send_key_combination("ret") application = get_application( application_type, application_name, self._qs, self._on_change, **kwargs ) sleep(5) # wait for application to be opened # GNOME focuses own applications automatically, but not external ones # FIXME: This will only work if firefox is not opened multiple times if application_name == "Firefox": self._qs.send_key_combination("meta_l") self._qs.send_text(application_name, True) return application
[docs] def focus_application(self, application: GenericApplication): if application.focused: return if application not in self._applications: raise ValueError( f"Could not focus on application {application.name} as it is not open" ) if len([app for app in self._applications if application.name == app.name]) > 1: raise NotImplementedError( "Selection of this kind is not implemented right now." ) else: self._qs.send_key_combination("meta_l") self._qs.send_text(application.name, True) self._on_change( ApplicationEvent.FOCUS_SHIFTED, application_reference=application )
[docs] def login(self, username: str, password: str): # TODO: GNOME has two different login screens --> determine which one # to select different users <-- standard login screen after startup # the other if a user session is already active and the user is preselected if not self._user_selected: # normal login screen with multiple users to select # TODO: select the correct user -> text recognition and selection recognition necessary pass self._qs.send_key_combination("ret") # select user sleep(0.5) # necessary, so password can be typed in correctly self._qs.send_text(password, True) sleep(5) # wait for desktop env to come up # TODO: determine when desktop env is ready self._session_unlocked = True self._qs.mouse.init()
[docs] def system_power_down(self): """Power down the system via GUI functionality. Send a power-down request via QEMU to the guest (domain is not available and qemu controls direct key inputs), and confirms the power-down message. This is by far the most graceful and fastest way to shut down a domain. Notes: Works in lock screen as well. """ try: self._qs.direct_command("system_powerdown") self._qs.send_key_combination("tab") self._qs.send_key_combination("ret") sleep(3) except libvirt.libvirtError: # TODO: Find better way than excepting the error pass # in tests the domain might be powered down by virSession teardown, which results in an exception
# try: # while self._qs.direct_command("info status") is not None: # sleep(1) # except libvirt.libvirtError as e: # if str(e).find("domain is not running"): # return # else: # raise e
[docs] def run_a_command(self, command: str): """Opens GNOME's 'Run a Command' dialogue and enters the provided command. Notes: Please do not use this method to open applications, as the dialogue is unreliable with names Args: command: command to be entered """ self._qs.send_key_combination("alt-f2") self._qs.send_text(command, True)