import functools
import os
import pathlib
import stat
import subprocess
import sys
import time
import unittest
from typing import Final
from appium import webdriver
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.webelement import WebElement
from gi.repository import Gio, GLib
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from desktoptest import start_plasmashell
class PanelFocusTest(unittest.TestCase):
"""
Tests for panel focus
"""
driver: webdriver.Remote
kactivitymanagerd: subprocess.Popen | None = None
kded: subprocess.Popen | None = None
plasmashell: subprocess.Popen | None = None
@classmethod
def setUpClass(cls) -> None:
"""
Initializes the webdriver
"""
cls.kactivitymanagerd, cls.kded, cls.plasmashell = start_plasmashell()
options = AppiumOptions()
options.set_capability("app", "Root")
options.set_capability("timeouts", {'implicit': 30000})
cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', options=options)
def tearDown(self) -> None:
"""
Take screenshot when the current test fails
"""
if not self._outcome.result.wasSuccessful():
self.driver.get_screenshot_as_file(f"failed_test_shot_plasmashell_#{self.id()}.png")
@classmethod
def tearDownClass(cls) -> None:
"""
Make sure to terminate the driver again, lest it dangles.
"""
cls.driver.quit()
def test_0_peek_at_desktop_not_giving_panel_focus(self) -> None:
"""
This clicks on the Peek at Desktop element and checks that the panel has
not gained keyboard focus by checking for the invisibility of the panel
focus indicator.
"""
el = self.driver.find_element(by=AppiumBy.NAME, value="Peek at Desktop")
el.click()
WebDriverWait(self.driver, 6).until(EC.visibility_of_element_located((AppiumBy.NAME, "Minimize All Applet Active Indicator")))
WebDriverWait(self.driver, 6).until(EC.invisibility_of_element_located((AppiumBy.NAME, "Panel Focus Indicator")))
el.click()
def test_1_setting_focus_shortcut(self) -> None:
"""
We set a shortcut for the panel, we activate it, and we check that the panel
focus indicator is indeed visible.
"""
session_bus: Gio.DBusConnection = Gio.bus_get_sync(Gio.BusType.SESSION)
message = Gio.DBusMessage.new_method_call("org.kde.kglobalaccel", "/component/plasmashell", "org.kde.kglobalaccel.Component", "allShortcutInfos")
reply, _ = session_bus.send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE, 1000)
shortcut_list = reply.get_body().get_child_value(0)
before = set(shortcut_list.get_child_value(i).get_child_value(0).get_string() for i in range(shortcut_list.n_children()))
actions = ActionChains(self.driver)
actions.context_click(self.driver.find_element(by=AppiumBy.NAME, value="Peek at Desktop"))
actions.pause(0.4)
actions.send_keys(Keys.ARROW_UP)
actions.pause(0.1)
actions.send_keys(Keys.ENTER)
actions.perform()
setter = self.driver.find_element(by=AppiumBy.NAME, value="Focus Shortcut Setter")
actions.click(setter)
actions.key_down(Keys.ALT)
actions.send_keys("a")
actions.key_up(Keys.ALT)
actions.pause(1.5)
actions.send_keys(Keys.ESCAPE)
actions.perform()
actions.pause(0.5)
actions.context_click()
actions.pause(0.1)
actions.send_keys(Keys.ARROW_UP)
actions.pause(0.1)
actions.send_keys(Keys.ENTER)
actions.pause(1)
actions.perform()
message = Gio.DBusMessage.new_method_call("org.kde.kglobalaccel", "/component/plasmashell", "org.kde.kglobalaccel.Component", "allShortcutInfos")
reply, _ = session_bus.send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE, 1000)
shortcut_list = reply.get_body().get_child_value(0)
after = set(shortcut_list.get_child_value(i).get_child_value(0).get_string() for i in range(shortcut_list.n_children()))
difference = after - before
self.assertTrue(len(difference) == 1)
launcher_shortcut_id = difference.pop()
message = Gio.DBusMessage.new_method_call("org.kde.kglobalaccel", "/component/plasmashell", "org.kde.kglobalaccel.Component", "invokeShortcut")
message.set_body(GLib.Variant("(s)", [launcher_shortcut_id]))
session_bus.send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE, 1000)
WebDriverWait(self.driver, 6).until(EC.visibility_of_element_located((AppiumBy.NAME, "Panel Focus Indicator")))
if __name__ == '__main__':
assert subprocess.call(["pidof", "plasmashell"]) != 0, "The test requires plasmashell to quit"
unittest.main()