1
0

utils.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import json
  2. import this
  3. import time
  4. import uiautomator2 as u2
  5. class UiElement(object):
  6. def __init__(self, d: u2.Device, xpath: str = None, description: str = None, debug: bool = True, point: dict = None) -> None:
  7. x, y = 0, 0
  8. self.info = {}
  9. self.d = d
  10. self.debug = debug
  11. if point is not None:
  12. self.info['point'] = point
  13. self.info['xpath'] = xpath
  14. self.info['description'] = description
  15. return
  16. if xpath is not None:
  17. self.info['xpath'] = xpath
  18. el = d.xpath(xpath)
  19. x, y = el.center()
  20. elif description is not None:
  21. self.info['description'] = description
  22. el = d(description=description)
  23. x, y = el.center()
  24. self.info['point'] = {'x': x, 'y': y}
  25. def log(self, *args, sep=' ', end='\n', file=None):
  26. if self.debug:
  27. print(args, sep=sep, end=end, file=file)
  28. def click(self):
  29. """
  30. 点击
  31. """
  32. point = self.info['point']
  33. self.log("点击元素:", self.info)
  34. self.d.shell(f"input tap {point['x']} {point['y']}")
  35. def text(self, text: str = None):
  36. """
  37. 设置文本框内容
  38. text 文本内容
  39. """
  40. point = self.info['point']
  41. self.log("点击元素:", self.info)
  42. self.d.shell(f"input tap {point['x']} {point['y']}")
  43. self.log("设置文本:", text)
  44. self.d.shell(f"input text '{text}'") # 输入文本内容
  45. def clear(self, length: int = 10):
  46. """
  47. 清空文本框
  48. """
  49. point = self.info['point']
  50. self.log("点击元素:", self.info)
  51. self.d.shell(f"input tap {point['x'] + length} {point['y']}")
  52. self.log("清空文本框:")
  53. # 模拟删除键输入
  54. # self.d.shell(f"for i in {{1..{20}}}; do input keyevent KEYCODE_CLEAR; done") # 20 次删除键事件
  55. for _ in range(length):
  56. self.d.shell("input keyevent 67")
  57. class UiFactory(object):
  58. _cache = {}
  59. def __init__(self, serial: str):
  60. """
  61. :param serial: 设备序列号。 例如 127.0.0.1:6555
  62. 可以通过 `adb devices` 获取
  63. """
  64. self.d = u2.connect(serial)
  65. pass
  66. def xpath(self, alisa: str, xpath: str = None):
  67. """
  68. 通过 xpath获取坐标
  69. alisa 别名
  70. """
  71. if alisa in self._cache:
  72. return self._cache[alisa]
  73. el = UiElement(self.d, xpath=xpath)
  74. self._cache[alisa] = el
  75. return el
  76. def desc(self, alisa: str, desc: str = None):
  77. if alisa in self._cache:
  78. return self._cache[alisa]
  79. el = UiElement(self.d, description=desc)
  80. self._cache[alisa] = el
  81. return el
  82. def load_point(self):
  83. __tmp__ = {}
  84. with open("deepcion_point.json", "r", encoding="utf-8") as f:
  85. __tmp__ = json.load(f)
  86. for k, v in __tmp__.items():
  87. if 'xpath' in v:
  88. self._cache[k] = UiElement(self.d, xpath=v['xpath'], point=v['point'])
  89. elif 'description' in v:
  90. self._cache[k] = UiElement(self.d, description=v['description'], point=v['point'])
  91. def save_point(self):
  92. """
  93. 保存坐标
  94. """
  95. __tmp__ = {}
  96. for k, v in self._cache.items():
  97. __tmp__[k] = v.info
  98. with open("deepcion_point.json", "w", encoding="utf-8") as f:
  99. json.dump(__tmp__, f, ensure_ascii=False, indent=4)
  100. def check_app_running(self, appid: str):
  101. # 获取所有运行的APP
  102. running_apps = self.d.app_list_running()
  103. print("安装列表:", running_apps)
  104. # 如果app没有启动, 启动APP
  105. if appid not in running_apps:
  106. print(f"{appid} 重新启动")
  107. self.d.app_start(appid)
  108. return True
  109. return False