File indexing completed on 2024-05-12 09:39:30

0001 #!/usr/bin/env python3
0002 
0003 # SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
0004 # SPDX-License-Identifier: MIT
0005 
0006 import subprocess
0007 import sys
0008 import unittest
0009 from typing import Final
0010 
0011 from appium import webdriver
0012 from appium.options.common.base import AppiumOptions
0013 from appium.webdriver.common.appiumby import AppiumBy
0014 from selenium.webdriver.support import expected_conditions as EC
0015 from selenium.webdriver.support.ui import WebDriverWait
0016 
0017 WIDGET_ID: Final = "org.kde.plasma.cameraindicator"
0018 
0019 
0020 class CameraIndicatorTest(unittest.TestCase):
0021     """
0022     Tests for the camera indicator widget
0023     """
0024 
0025     driver: webdriver.Remote
0026     pipewire_already_running_before_test: bool = False
0027 
0028     @classmethod
0029     def setUpClass(cls) -> None:
0030         """
0031         Opens the widget and initialize the webdriver
0032         """
0033         options = AppiumOptions()
0034         options.set_capability("app", f"plasmawindowed -p org.kde.plasma.nano {WIDGET_ID}")
0035         options.set_capability("environ", {
0036             "QT_FATAL_WARNINGS": "1",
0037             "QT_LOGGING_RULES": "qt.accessibility.atspi.warning=false;kf.plasma.core.warning=false;kf.windowsystem.warning=false;kf.kirigami.platform.warning=false;kpipewire_logging.warning=false",
0038         })
0039         options.set_capability("timeouts", {'implicit': 10000})
0040         cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', options=options)
0041 
0042         cls.pipewire_already_running_before_test = subprocess.Popen(["pidof", "pipewire"]).wait() == 0
0043 
0044     def tearDown(self) -> None:
0045         """
0046         Take screenshot when the current test fails
0047         """
0048         if not self._outcome.result.wasSuccessful():
0049             self.driver.get_screenshot_as_file(f"failed_test_shot_cameraindicatortest_#{self.id()}.png")
0050 
0051     @classmethod
0052     def tearDownClass(cls) -> None:
0053         """
0054         Make sure to terminate the driver again, lest it dangles.
0055         """
0056         cls.driver.quit()
0057 
0058     def test_0_open(self) -> None:
0059         """
0060         Tests the widget can be opened
0061         """
0062         if self.pipewire_already_running_before_test:
0063             self.driver.find_element(AppiumBy.NAME, "No camera is in use")
0064         else:
0065             self.driver.find_element(AppiumBy.NAME, "Camera indicator is unavailable")
0066 
0067     def test_10_connect_to_pipewire(self) -> None:
0068         """
0069         Tests the widget can connect to pipewire
0070         """
0071         if self.pipewire_already_running_before_test:
0072             self.skipTest("Pipewire is already running.")
0073 
0074         pipewire = subprocess.Popen(["pipewire"], stdout=sys.stderr, stderr=sys.stderr)
0075         self.addCleanup(pipewire.terminate)
0076 
0077         # Reconnecting takes at least 5s
0078         WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((AppiumBy.NAME, "No camera is in use")))
0079 
0080         pipewire.terminate()
0081         self.driver.find_element(AppiumBy.NAME, "Camera indicator is unavailable")
0082 
0083 
0084 if __name__ == '__main__':
0085     unittest.main()