File indexing completed on 2024-05-19 05:37:30

0001 #!/usr/bin/env python3
0002 
0003 # SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
0004 # SPDX-License-Identifier: MIT
0005 
0006 import base64
0007 import os
0008 import shutil
0009 import subprocess
0010 import tempfile
0011 import time
0012 import unittest
0013 from typing import Final
0014 
0015 import cv2 as cv
0016 import numpy as np
0017 from appium import webdriver
0018 from appium.options.common.base import AppiumOptions
0019 from appium.webdriver.common.appiumby import AppiumBy
0020 from gi.repository import GLib
0021 
0022 KDE_VERSION: Final = 6
0023 KCM_ID: Final = "kcm_cursortheme"
0024 
0025 
0026 class KCMCursorThemeTest(unittest.TestCase):
0027     """
0028     Tests for kcm_cursortheme
0029     """
0030 
0031     driver: webdriver.Remote
0032 
0033     @classmethod
0034     def setUpClass(cls) -> None:
0035         """
0036         Opens the KCM and initialize the webdriver
0037         """
0038         # Install the custom cursor theme
0039         user_data_dir: Final[str] = GLib.get_user_data_dir()
0040         icons_folder: Final = os.path.join(user_data_dir, "icons")
0041         if not os.path.exists(icons_folder):
0042             os.mkdir(icons_folder)
0043             cls.addClassCleanup(lambda: shutil.rmtree(icons_folder))
0044 
0045         icon_theme_folder: Final = os.path.join(user_data_dir, "icons", "testcursortheme")
0046         assert not os.path.exists(icon_theme_folder)
0047         assert os.path.exists("../kcms/cursortheme/autotests/data/testcursortheme")
0048         shutil.copytree("../kcms/cursortheme/autotests/data/testcursortheme", icon_theme_folder)
0049         cls.addClassCleanup(lambda: shutil.rmtree(icon_theme_folder))
0050 
0051         options = AppiumOptions()
0052         options.set_capability("app", f"kcmshell{KDE_VERSION} {KCM_ID}")
0053         options.set_capability("timeouts", {'implicit': 10000})
0054         # From XCURSORPATH
0055         options.set_capability("environ", {
0056             "XCURSOR_PATH": icons_folder,
0057             "QT_LOGGING_RULES": "kcm_cursortheme.debug=true",
0058         })
0059         cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', options=options)
0060 
0061     def tearDown(self) -> None:
0062         """
0063         Take screenshot when the current test fails
0064         """
0065         if not self._outcome.result.wasSuccessful():
0066             self.driver.get_screenshot_as_file(f"failed_test_shot_{KCM_ID}_#{self.id()}.png")
0067 
0068     @classmethod
0069     def tearDownClass(cls) -> None:
0070         """
0071         Make sure to terminate the driver again, lest it dangles.
0072         """
0073         cls.driver.quit()
0074 
0075     def test_0_open(self) -> None:
0076         """
0077         Tests the KCM can be opened
0078         """
0079         self.driver.find_element(AppiumBy.NAME, "&Configure Launch Feedback…")
0080         self.driver.find_element(AppiumBy.NAME, "Test Cursor Theme (DO NOT TRANSLATE)")
0081 
0082     def test_1_cursor_theme_preview(self) -> None:
0083         """
0084         Tests if the cursor preview is loaded
0085         """
0086         time.sleep(3)  # Wait until the window appears
0087 
0088         with tempfile.TemporaryDirectory() as temp_dir:
0089             saved_image_path: str = os.path.join(temp_dir, "kcm_window.png")
0090             subprocess.check_call(["import", "-window", "root", saved_image_path])
0091 
0092             cv_first_image = cv.imread(saved_image_path, cv.IMREAD_COLOR)
0093             first_image = base64.b64encode(cv.imencode('.png', cv_first_image)[1].tobytes()).decode()
0094 
0095         # Red
0096         cv_second_image = np.zeros((16, 16, 3), dtype=np.uint8)
0097         cv_second_image[:, :] = [0, 0, 255]
0098         second_image = base64.b64encode(cv.imencode('.png', cv_second_image)[1].tobytes()).decode()
0099         self.driver.find_image_occurrence(first_image, second_image)
0100         # Green
0101         cv_second_image[:, :] = [0, 255, 0]
0102         second_image = base64.b64encode(cv.imencode('.png', cv_second_image)[1].tobytes()).decode()
0103         self.driver.find_image_occurrence(first_image, second_image)
0104         # Blue
0105         cv_second_image[:, :] = [255, 0, 0]
0106         second_image = base64.b64encode(cv.imencode('.png', cv_second_image)[1].tobytes()).decode()
0107         self.driver.find_image_occurrence(first_image, second_image)
0108         # Yellow
0109         cv_second_image[:, :] = [0, 255, 255]
0110         second_image = base64.b64encode(cv.imencode('.png', cv_second_image)[1].tobytes()).decode()
0111         self.driver.find_image_occurrence(first_image, second_image)
0112 
0113     def test_2_launch_feedback_dialog(self) -> None:
0114         self.driver.find_element(AppiumBy.NAME, "&Configure Launch Feedback…").click()
0115         self.driver.find_element(AppiumBy.NAME, "Blinking")
0116 
0117 
0118 if __name__ == '__main__':
0119     unittest.main()