from __future__ import annotations import sys import unittest from pathlib import Path from unittest.mock import MagicMock, patch ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / "scripts")) from service.desktop_session import ( # noqa: E402 DesktopRpaError, WindowCandidate, activate_window, resolve_unique_window, ) from service import uia_locator # noqa: E402 from util.selectors import ElementSpec, MAIN_WINDOW # noqa: E402 class SelectorContractTest(unittest.TestCase): def test_unique_window_is_required(self) -> None: candidate = WindowCandidate(1, 10, "WXWork", "WeWorkWindow", "企业微信", True) self.assertEqual( resolve_unique_window(MAIN_WINDOW, candidates=[candidate]), candidate, ) def test_duplicate_windows_fail_instead_of_taking_first(self) -> None: candidates = [ WindowCandidate(1, 10, "WXWork", "WeWorkWindow", "企业微信", True), WindowCandidate(2, 11, "WXWork", "WeWorkWindow", "企业微信", True), ] with self.assertRaises(DesktopRpaError) as ctx: resolve_unique_window(MAIN_WINDOW, candidates=candidates) self.assertEqual(ctx.exception.code, "ELEMENT_AMBIGUOUS") def test_hidden_window_is_not_a_candidate(self) -> None: hidden = WindowCandidate(1, 10, "WXWork", "WeWorkWindow", "企业微信", False) with self.assertRaises(DesktopRpaError) as ctx: resolve_unique_window(MAIN_WINDOW, candidates=[hidden]) self.assertEqual(ctx.exception.code, "WINDOW_NOT_FOUND") def test_activate_without_maximize_skips_restore_when_zoomed(self) -> None: window = WindowCandidate(42, 10, "WXWork", "WeWorkWindow", "企业微信", True) with patch("service.desktop_session.user32") as user32: user32.IsIconic.return_value = False user32.IsZoomed.return_value = True user32.SetForegroundWindow.return_value = True activate_window(window, maximize=False) user32.ShowWindow.assert_not_called() user32.SetForegroundWindow.assert_called_once_with(42) def test_activate_maximize_when_not_zoomed(self) -> None: window = WindowCandidate(42, 10, "WXWork", "WeWorkWindow", "企业微信", True) with patch("service.desktop_session.user32") as user32: user32.IsIconic.return_value = False user32.IsZoomed.return_value = False user32.SetForegroundWindow.return_value = True activate_window(window, maximize=True) user32.ShowWindow.assert_called() user32.SetForegroundWindow.assert_called_once_with(42) def test_locate_unique_matches_child_value(self) -> None: row = MagicMock() row.Name = "status_layout" row.AutomationId = "" row.ControlTypeName = "TreeControl" row.ClassName = "" label = MagicMock() label.Name = "main_chattext" label.GetChildren.return_value = [] row.GetChildren.return_value = [label] root = MagicMock() root.Name = "wlist_view" root.AutomationId = "" root.ControlTypeName = "TreeControl" root.ClassName = "" root.GetChildren.return_value = [row] with patch.object(uia_locator, "control_value", side_effect=lambda c: "新的客户" if c is label else ""): spec = ElementSpec( "new_customer_row", name="status_layout", ancestor_name="wlist_view", child_value_name="main_chattext", value="新的客户", ) # ancestor is root itself when searching from root with name wlist_view found = uia_locator.locate_unique(root, ElementSpec("wlist", name="wlist_view")) self.assertIs(found, root) found_row = uia_locator.locate_unique(root, spec) self.assertIs(found_row, row) if __name__ == "__main__": unittest.main()