File indexing completed on 2024-05-12 05:35:22
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 subprocess 0009 import sys 0010 import tempfile 0011 import time 0012 import unittest 0013 0014 import cv2 as cv 0015 import gi 0016 0017 gi.require_version('Gtk', '4.0') 0018 from appium import webdriver 0019 from appium.options.common.base import AppiumOptions 0020 from appium.webdriver.common.appiumby import AppiumBy 0021 from desktoptest import start_kactivitymanagerd, start_kded 0022 from gi.repository import Gtk 0023 from selenium.common.exceptions import TimeoutException 0024 from selenium.webdriver.common.actions.action_builder import ActionBuilder 0025 from selenium.webdriver.common.actions.interaction import POINTER_TOUCH 0026 from selenium.webdriver.common.actions.pointer_input import PointerInput 0027 from selenium.webdriver.support import expected_conditions as EC 0028 from selenium.webdriver.support.ui import WebDriverWait 0029 0030 0031 class Bug477220Test(unittest.TestCase): 0032 0033 driver: webdriver.Remote 0034 kactivitymanagerd: subprocess.Popen | None = None 0035 kded: subprocess.Popen | None = None 0036 0037 @classmethod 0038 def setUpClass(cls) -> None: 0039 cls.kactivitymanagerd = start_kactivitymanagerd() 0040 cls.kded = start_kded() 0041 0042 options = AppiumOptions() 0043 options.set_capability("app", "plasmashell -p org.kde.plasma.desktop --no-respawn") 0044 options.set_capability("environ", { 0045 "QT_LOGGING_RULES": "kf.kirigami.platform.warning=false", 0046 }) 0047 options.set_capability("timeouts", {'implicit': 30000}) 0048 cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', options=options) 0049 0050 def tearDown(self) -> None: 0051 """ 0052 Take screenshot when the current test fails 0053 """ 0054 if not self._outcome.result.wasSuccessful(): 0055 self.driver.get_screenshot_as_file(f"failed_test_shot_bug476968_#{self.id()}.png") 0056 0057 @classmethod 0058 def tearDownClass(cls) -> None: 0059 """ 0060 Make sure to terminate the driver again, lest it dangles. 0061 """ 0062 subprocess.check_output(["kquitapp6", "plasmashell"], stderr=sys.stderr) 0063 if cls.kded: 0064 cls.kded.kill() 0065 if cls.kactivitymanagerd: 0066 cls.kactivitymanagerd.kill() 0067 cls.driver.quit() 0068 0069 def test_1_bug478958_touch_long_press_on_desktop(self) -> None: 0070 """ 0071 Long press on the desktop to enter the edit mode 0072 """ 0073 time.sleep(3) 0074 screen_geometry = Gtk.Window().get_display().get_monitors()[0].get_geometry() 0075 long_press_time_ms: int = Gtk.Settings.get_default().get_property("gtk-long-press-time") * 2 + 5000 0076 self.assertGreater(screen_geometry.width, 100) 0077 self.assertGreater(screen_geometry.height, 100) 0078 0079 # Click "More" to open the desktop context menu 0080 wait = WebDriverWait(self.driver, 5) 0081 success = False 0082 for _ in range(20): 0083 try: 0084 # Work around "no target window" 0085 action = ActionBuilder(self.driver, mouse=PointerInput(POINTER_TOUCH, "finger")) 0086 action.pointer_action.move_to_location(int(screen_geometry.width / 2), int(screen_geometry.height / 2)).click() 0087 action.perform() 0088 action = ActionBuilder(self.driver, mouse=PointerInput(POINTER_TOUCH, "finger")) 0089 action.pointer_action.move_to_location(int(screen_geometry.width / 2), int(screen_geometry.height / 2)).pointer_down().pause(long_press_time_ms / 1000).pointer_up() 0090 action.perform() 0091 wait.until(EC.presence_of_element_located((AppiumBy.NAME, "More"))).click() 0092 success = True 0093 break 0094 except TimeoutException: 0095 continue 0096 self.assertTrue(success) 0097 0098 def test_2_bug477220_open_context_menu(self) -> None: 0099 """ 0100 "More" button in the desktop toolbox does not open the context menu 0101 """ 0102 time.sleep(3) # Wait until the menu appears 0103 with tempfile.TemporaryDirectory() as temp_dir: 0104 saved_image_path: str = os.path.join(temp_dir, "desktop.png") 0105 self.assertTrue(self.driver.get_screenshot_as_file(saved_image_path)) 0106 0107 cv_first_image = cv.imread(saved_image_path, cv.IMREAD_COLOR) 0108 first_image = base64.b64encode(cv.imencode('.png', cv_first_image)[1].tobytes()).decode() 0109 0110 cv_expected_image = cv.imread(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "bug478958_new_file_menu_item_icon.png"), cv.IMREAD_COLOR) 0111 expected_image = base64.b64encode(cv.imencode('.png', cv_expected_image)[1].tobytes()).decode() 0112 self.driver.find_image_occurrence(first_image, expected_image, threshold=1e-7) 0113 0114 # Click an empty area to close the menu 0115 screen_geometry = Gtk.Window().get_display().get_monitors()[0].get_geometry() 0116 action = ActionBuilder(self.driver, mouse=PointerInput(POINTER_TOUCH, "finger")) 0117 action.pointer_action.move_to_location(int(screen_geometry.width / 2), int(screen_geometry.height / 2)).click() 0118 action.perform() 0119 0120 0121 if __name__ == '__main__': 0122 unittest.main()