UAT_runner.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. # -*- coding:utf-8 -*-
  2. from UAT_PathManage import UATPathManage
  3. from ssat_sdk.UATree.UAT_tree import UATTree
  4. from ssat_sdk.UATree.UAT_treeConstant import TreeConst
  5. from UAT_runnerCommand import UATRunnerCommand
  6. from ssat_sdk.python_uiautomator import PyUIAutomator, FocusManageAndroid, DirectionManageAndroid
  7. from UAT_log import error, debug, info
  8. import os, sys, time
  9. DEBUG = True
  10. INFO =True
  11. ERROR = True
  12. class UATRunner():
  13. cls = "UATRunner"
  14. def __init__(self):
  15. self.uatPathManage = UATPathManage()
  16. self.pyU = PyUIAutomator()
  17. self.dm = DirectionManageAndroid()
  18. self.fm = FocusManageAndroid(self.pyU, self.dm)
  19. self.runnerCmd = UATRunnerCommand(self.uatPathManage, self.pyU, self.dm, self.fm)
  20. # setOptionValue之后需要一个退回的pathlist来退出菜单
  21. self.executedPath = []
  22. '''
  23. 当电视重启以后,uiautomator连接会断开,需要重新赋予UATRunner一个可用的连接对象
  24. '''
  25. def rebuildUiAutomator(self, pyUIAutomator, directionManageAndroid, focusManageAndroid):
  26. self.pyU = pyUIAutomator
  27. self.dm = directionManageAndroid
  28. self.fm = focusManageAndroid
  29. self.runnerCmd = UATRunnerCommand(self.uatPathManage, self.pyU, self.dm, self.fm)
  30. '''
  31. 返回option的object
  32. '''
  33. def getOptionObject(self, option):
  34. className = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Class]
  35. desc = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Desc]
  36. resId = option[UATTree.TAB_OPTION_VIEW][UATTree.View_ID]
  37. text = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Text]
  38. return self.pyU.getUiObject(className=className, resourceId=resId, description=desc, text=text)
  39. '''
  40. 根据parent的layout和一个option判断在 UATree中的哪个界面,或者还没有进入UATree界面中
  41. :return parent数据,或者None。None代表未进入UATree界面中
  42. '''
  43. def locateParentUI(self):
  44. cparent = None
  45. treeDict = self.uatPathManage.uatData.getTreeDict()
  46. # print "locateParentUI: treeDict levels:",treeDict.keys()
  47. parentList = []
  48. levelList = treeDict.keys()
  49. flag = False
  50. for index in range(levelList.__len__()-1, -1, -1):
  51. level = levelList[index]
  52. # print "locateParentUI,level:", index, level
  53. levelDict = treeDict[level]
  54. for parent in levelDict:
  55. parentDict = levelDict[parent]
  56. layout = parentDict["layout"]
  57. # print "locateParentUI: layout:", layout
  58. ret = self.runnerCmd.checkParentChoose(parentDict)
  59. if ret > 0:
  60. cparent = parentDict
  61. flag = True
  62. break
  63. if flag == True:
  64. break
  65. if cparent is None:
  66. info(self.cls, "locateParentUI", "没有选中Parent,电视界面不知道在哪里", INFO)
  67. else:
  68. info(self.cls, "locateParentUI", "选中Parent:" + cparent[UATTree.TAB_NAME], INFO)
  69. print "ParentParam:", cparent
  70. return cparent
  71. '''
  72. 在该option所在页面下,聚焦到目标option
  73. '''
  74. def moveToOption(self, option):
  75. parent = self.uatPathManage.uatData.getParentByOption(option)
  76. return self.runnerCmd.focusTargetOption(parent, option)
  77. '''
  78. :return -1 执行失败,放弃重新定位执行;0 执行失败,重新定位执行; 1 执行成功
  79. '''
  80. def runForwardPath(self, backPath, forwardPath):
  81. fLen = forwardPath.__len__()
  82. fParent = forwardPath[fLen-1]
  83. # 当backPath和forwardPath的父交点为first层时,不能走shortcut_key,否则会导致执行出现问题(USB界面)
  84. if fParent[UATTree.TAB_LEVEL] == "first" \
  85. and backPath.__len__() < 2:
  86. ret = self.openFirstParent(fParent, forwardPath)
  87. if ret < 1: #注意打开firstparent界面成功,定位错误,会重新定位。场景:usb
  88. return ret
  89. # 逐步进入后面的parent页面
  90. else:
  91. ret = self.goMidPath(fParent, forwardPath[1: fLen- 1])
  92. if ret is False:
  93. return -1
  94. #在目标parent中,选中目标option
  95. return self.moveToOption(forwardPath[0])
  96. else:
  97. ret = self.goMidPath(forwardPath[fLen - 1], forwardPath[1:fLen - 1])
  98. if ret is False:
  99. return -1
  100. # 在目标parent中,选中目标option
  101. return self.moveToOption(forwardPath[0])
  102. '''
  103. 打开第一个页面
  104. :return: -1 代表activity打开失败,0 代表activity打开成功,焦点不在parent layout中;1 表示页面打开成功,焦点在parent layout中
  105. -2 表示处理弹窗的过程中失败了
  106. '''
  107. def openFirstParent(self, fParent, forwardPath):
  108. info(self.cls, "openFirstParent", "GOTO first parent " + fParent[UATTree.TAB_NAME], INFO)
  109. flag = self.runnerCmd.executeShortCutKey(fParent)
  110. if flag is False:
  111. error(self.cls, "openFirstParent", "Open first parent%s fail."%(fParent[UATTree.TAB_NAME]), ERROR)
  112. return -1
  113. ret = self.runnerCmd.executeDialog(fParent)
  114. if ret < 1:
  115. return -2
  116. flag1 = self.runnerCmd.checkParentChoose(fParent)
  117. if flag1 < 1:
  118. error(self.cls, "openFirstParent", "Open first parent activity.But parent %s not foucsed." % (fParent[UATTree.TAB_NAME]), ERROR)
  119. return 0
  120. return 1
  121. def goMidPath(self, curParent, midParentList):
  122. mLen = midParentList.__len__()
  123. for index in range(mLen-1, -1, -1):
  124. parent = midParentList[index]
  125. info(self.cls, "goMidPath", "GOTO parent %s from parent %s "%(parent[UATTree.TAB_NAME], curParent[UATTree.TAB_NAME]), INFO)
  126. ret = self.gotoNextParent(curParent, parent, midParentList)
  127. if ret == 0:
  128. return False
  129. curParent = parent
  130. return True
  131. '''
  132. :return 0:代表失败;1代表enterKey发送成功,进入下一个界面
  133. '''
  134. def gotoNextParent(self, curParent, targetParent, parentList):
  135. targetOptionName = targetParent[UATTree.TAB_NAME]
  136. targetOption = curParent[UATTree.TAB_OPTION][targetOptionName]
  137. flag = self.moveToOption(targetOption)
  138. if flag is False:
  139. return 0
  140. info(self.cls, "gotoNextParent", "moveToOption:%s done! executing enter key!"%targetOption[UATTree.TAB_NAME], INFO)
  141. ret = self.runnerCmd.executeKey(targetOption[UATTree.TAB_ENTER_KEY])
  142. if ret is False:
  143. error(self.cls, "gotoNextParent",
  144. "Send parent %s enter key fail." % (curParent[UATTree.TAB_NAME]), ERROR)
  145. return 0
  146. else:
  147. ret = self.runnerCmd.executeDialog(targetParent)
  148. return ret
  149. '''
  150. 执行backPath
  151. :return true成功,false失败
  152. '''
  153. def runBackPath(self, backPath):
  154. bLen = backPath.__len__()
  155. if bLen <= 1:
  156. return False
  157. if bLen == 2:
  158. return True
  159. for index in range(1, bLen-1):
  160. curParent = backPath[index]
  161. prevParent = backPath[index+1]
  162. info(self.cls, "runBackPath", "back to parent %s from parent %s."
  163. %(backPath[index][UATTree.TAB_NAME], backPath[index+1][UATTree.TAB_NAME]), INFO)
  164. flag = self.backToPrevParent(curParent, prevParent)
  165. if flag is False:
  166. return False
  167. return True
  168. def backToPrevParent(self, curParent, targetParent):
  169. backKeys = curParent[UATTree.TAB_TOPARENT_KEY]
  170. self.runnerCmd.executeKey(backKeys)
  171. dialog_A = curParent[UATTree.TAB_UI_VIEW][UATTree.UIView_Dialog_B]
  172. if dialog_A.__len__() > 0:
  173. ret = self.runnerCmd.executeDialog(curParent, isForward=False)
  174. if ret == 0:
  175. return False
  176. flag = self.runnerCmd.checkParentChoose(targetParent)
  177. if flag < 1:
  178. error(self.cls, "backToPrevParent",
  179. "back to parent %s from parent %s fail." % (targetParent[UATTree.TAB_NAME], curParent[UATTree.TAB_NAME]), ERROR)
  180. return False
  181. return True
  182. '''
  183. fromFirst:表示是否指定从FirstParent打开开始路径执行。
  184. count:递归控制变量,执行路径的最大尝试次数
  185. '''
  186. def focusOption(self, option, fromFirst, count = 0):
  187. if fromFirst is True:
  188. curParent = None
  189. else:
  190. curParent = self.locateParentUI()
  191. backPath,forwardPath = self.uatPathManage.genOptionSmartPath(curParent, option)
  192. info(self.cls,"focusOption", "backPath:", INFO)
  193. self.uatPathManage.info(backPath)
  194. info(self.cls,"focusOption", "forwardPath:", INFO)
  195. self.uatPathManage.info(forwardPath)
  196. if forwardPath.__len__() == 0:
  197. return False
  198. if backPath.__len__() == 0 and forwardPath.__len__() >= 2:
  199. info(self.cls, "focusOption", "runBackPath success", INFO)
  200. ret = self.runForwardPath(backPath, forwardPath)
  201. self.executedPath = self.getExecutedPath(forwardPath)
  202. if ret ==0: #重新计算路径执行
  203. if count < 3:
  204. return self.focusOption(option, fromFirst, count+1)
  205. else:
  206. info(self.cls, "focusOption", "runForwardPath fail %s times, focusOption Fail!!!"%count, INFO)
  207. return False
  208. if backPath.__len__() >= 2 and forwardPath.__len__() >=2:
  209. backFlag = self.runBackPath(backPath)
  210. if backFlag is False:
  211. info(self.cls, "focusOption", "runBackPath fail", INFO)
  212. return False
  213. info(self.cls, "focusOption", "runBackPath success", INFO)
  214. goFlag = self.runForwardPath(backPath, forwardPath)
  215. self.executedPath = self.getExecutedPath(forwardPath)
  216. if goFlag < 1:
  217. info(self.cls, "focusOption", "runForwardPath fail", INFO)
  218. return False
  219. info(self.cls, "focusOption", "runForwardPath success", INFO)
  220. return True
  221. '''
  222. 回退路径,仅仅只是使用forwardPath的话,最后一个元素是option,但是实际上已经进入了这个界面,应该判断的是parent。
  223. 所以要把forwardPath里面的option替换为parent;如果没有配这个option对应的parent,则去掉该option,以便exitMenuByPath函数使用。
  224. '''
  225. def getExecutedPath(self, forwardPath):
  226. option = forwardPath[0]
  227. parentName = option[UATTree.TAB_NAME]
  228. parent = self.uatPathManage.uatData.getParentDict(parentName)
  229. if parent is None:
  230. forwardPath.remove(option)
  231. else:
  232. forwardPath[0] = parent
  233. return forwardPath
  234. '''
  235. 执行该option的EnterKey
  236. '''
  237. def sendOptionEnterKey(self, option):
  238. enterKey = option[UATTree.TAB_ENTER_KEY]
  239. return self.runnerCmd.executeKey(enterKey)
  240. '''
  241. 检查当前页面是否存在目标option
  242. '''
  243. def checkOptionExist(self, option):
  244. parent = self.uatPathManage.uatData.getParentByOption(option)
  245. if not self.runnerCmd.checkParentChoose(parent):
  246. return False
  247. return self.runnerCmd.checkOptionExist(option, parent)
  248. '''
  249. 在focusOption基础上,执行目标option的enter_key
  250. '''
  251. def openOption(self, option, fromFirst):
  252. ret = self.focusOption(option, fromFirst)
  253. if ret is False:
  254. return False
  255. print "executing enter key"
  256. ret = self.runnerCmd.executeKey(option[UATTree.TAB_ENTER_KEY])
  257. print "openOption, executeKey:%s"%ret
  258. parent = self.uatPathManage.uatData.getParentDict(option[UATTree.TAB_NAME])
  259. if parent is None:
  260. return ret
  261. else:
  262. return self.runnerCmd.executeDialog(parent)
  263. def openParent(self, parent, fromFirst):
  264. if parent[UATTree.TAB_LEVEL] == 'first':
  265. return self.openFirstParent(parent, "")
  266. else:
  267. prevOption = self.uatPathManage.uatData.getOption(parent[UATTree.TAB_NAME])
  268. return self.openOption(prevOption, fromFirst)
  269. def setOptionValue(self, option, value, exitMenu=True, fromFirst=True):
  270. ret = self.openOption(option, fromFirst)
  271. if ret is False:
  272. info(self.cls, "setOptionValue", "openOption过程执行失败!!!", INFO)
  273. if exitMenu is True:
  274. self.runnerCmd.exitMenuByPath(self.executedPath)
  275. return False
  276. ret1 = self.runnerCmd.setValue(option, value)
  277. if exitMenu is True:
  278. ret2 = self.runnerCmd.exitMenuByPath(self.executedPath)
  279. else:
  280. ret2 = True
  281. return (ret1 and ret2)
  282. def checkOptionInfoView(self, option, cmpText = "", cmpPic = ""):
  283. infoObj = self.getOptionInfoView(option)
  284. result, picPath, cutPicPath = self.runnerCmd.getUIObjPic(infoObj)
  285. if result is False:
  286. error(self.cls, "checkOptionInfoView", "Warning:option %s 截取infoView所在坐标图片失败!!!" % option["name"], ERROR)
  287. return -1, picPath, cutPicPath
  288. if cmpPic != "":
  289. result = self.runnerCmd.infoViewCmpPic(cmpPic, cutPicPath)
  290. return result, picPath, cutPicPath
  291. elif cmpText != "":
  292. result = self.runnerCmd.infoViewCmpText(cmpText, cutPicPath)
  293. return result, picPath, cutPicPath
  294. else:
  295. info(self.cls, "checkOptionInfoView", "未传入cmpText和cmpPic参数,仅检查infoView是否存在", INFO)
  296. if infoObj is None:
  297. error(self.cls, "checkOptionInfoView", "Warning:option %s 获取infoView失败!!!" % option["name"],
  298. ERROR)
  299. return -1, picPath, cutPicPath
  300. else:
  301. info(self.cls, "checkOptionInfoView", "已识别到option %s的infoView" % option["name"], INFO)
  302. return 1, picPath, cutPicPath
  303. def getOptionInfoView(self, option):
  304. optionView = option[UATTree.TAB_INFO_VIEW]
  305. viewId = optionView[UATTree.View_ID]
  306. viewText = optionView[UATTree.View_Text]
  307. viewDesc = optionView[UATTree.View_Desc]
  308. viewClass = optionView[UATTree.View_Class]
  309. if viewId.__len__() == 0:
  310. return None
  311. infoObj = self.pyU.getUiObject(resourceId=viewId, text=viewText, className=viewClass, description=viewDesc)
  312. return infoObj
  313. if __name__ == "__main__":
  314. uatRunner = UATRunner()
  315. option = uatRunner.uatPathManage.uatData.getOption("usb_video_h264-ac3")
  316. uatRunner.openOption(option, False)
  317. # print uatRunner.locateParentUI()
  318. # parent = uatRunner.uatPathManage.uatData.getParentDict("usb_bmp")
  319. # uatRunner.runnerCmd.checkParentChoose(parent)
  320. # print option
  321. # option = uatRunner.uatPathManage.uatData.getOption("usb_aac_option")
  322. # cmpPic = r"D:/SAT/tmp\1572432282.74_cutPic_[932, 548, 1812, 597].png"
  323. # result, picpath, cutPicPath = uatRunner.checkOptionInfoView(option, cmpPic=cmpPic)
  324. # uatRunner.moveToOption(option)
  325. # parent = uatRunner.locateParentUI()
  326. # print "locateParentUI,parent:", parent
  327. # option = uatRunner.uatPathManage.uatData.getOption("usb_brightness")
  328. # print uatRunner.setOptionValue(option, 50)