UAT_runnerCommand.py 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. # -*- coding:utf-8 -*-
  2. from UAT_tree import UATTree
  3. from ssat_sdk.python_uiautomator import PyUIAutomator,FocusManageAndroid, DirectionManageAndroid
  4. from UAT_log import error,debug,info
  5. from ssat_sdk.utils import string_util
  6. from ssat_sdk.tv_operator import TvOperator
  7. from ssat_sdk.device_manage.capturecard_manager import CCardManager
  8. from ssat_sdk.sat_environment import getSATTmpDIR
  9. from ssat_sdk.pic_tool import ImageCMP
  10. from ssat_sdk.ocr_convert import OCRConvert
  11. from ssat_sdk.utils.string_util import strcmp, getDigitFromString
  12. import cv2 as cv
  13. import os, sys, time
  14. DEBUG = True
  15. INFO =True
  16. ERROR = True
  17. class UATRunnerCommand():
  18. cls = "UATRunnerCommand"
  19. def __init__(self, uatPathManage, pyU, dm, fm):
  20. self.uatPathManage = uatPathManage
  21. self.pyU = pyU
  22. self.dm = dm
  23. self.fm = fm
  24. self.tvOperator = TvOperator()
  25. self.eventKeyCode = self.uatPathManage.uatData.getKeyCodeDict()
  26. self.CC = CCardManager()
  27. self.imgCMP = ImageCMP()
  28. self.ocrConvert = OCRConvert()
  29. #检测option组件是不是在电视上显示了
  30. def checkOptionExist(self, option, parent):
  31. #print "checkOptionExist,option:",option
  32. moveKey = parent[UATTree.TAB_MOVE_KEY]
  33. print "moveKey:", moveKey
  34. Max_Try = moveKey[UATTree.Max_Try]
  35. if Max_Try == "":
  36. Max_Try = 1
  37. else:
  38. Max_Try = int(Max_Try)
  39. Reverse_Max_Try = Max_Try * 2
  40. print "Max_Try:",Max_Try
  41. count = 0
  42. Reversecount = 0
  43. lastObj = ""
  44. while(True):
  45. if count >= Max_Try and Reversecount >= Reverse_Max_Try:
  46. break
  47. # 如果找到目标直接返回
  48. if self.pyU.isElementExist(resourceId=option["optionView"][UATTree.UIView_ID],
  49. text=option["optionView"][UATTree.UIView_Text],
  50. description=option["optionView"][UATTree.UIView_Desc]):
  51. return True
  52. # choosingObj = self.getChooseUIObj(option)
  53. # if lastObj != "":
  54. # if choosingObj.info == lastObj.info:
  55. # print "choosingObj.info == lastObj.info!!!!"
  56. # if count < Max_Try:
  57. # Max_Try = count
  58. # else:
  59. # break
  60. # lastObj = choosingObj
  61. if count < Max_Try:
  62. flag = 1
  63. count += 1
  64. print "now count:", count
  65. else:
  66. flag = 0
  67. Reversecount += 1
  68. print "now Reversecount:", Reversecount
  69. self.executeMoveKey(moveKey, flag)
  70. return False
  71. '''
  72. 检测option组件,在电视上是否被选中了
  73. :param option 数据字典
  74. :return -1:未进入option的页面,找不到option UIObject;0:进入了option的页面,未选中option;1 已经选中option
  75. -2:代表未找到焦点
  76. '''
  77. def checkOptionChoose(self, option):
  78. optionUIObj = self.pyU.getUiObject(text=option["optionView"][UATTree.View_Text],
  79. resourceId=option["optionView"][UATTree.View_ID],
  80. description=option["optionView"][UATTree.View_Desc])
  81. if optionUIObj is None or optionUIObj.count == 0:
  82. return -1
  83. curUIObj = self.getChooseUIObj(option)
  84. if curUIObj is None or curUIObj.count == 0:
  85. return -2
  86. if self.dm.isHasAnotherBounds(curUIObj.info["bounds"], optionUIObj.info['bounds']):
  87. return 1
  88. else:
  89. return 0
  90. '''
  91. 根据option配置的焦点方式,返回当前页面焦点组件
  92. '''
  93. def getChooseUIObj(self, option):
  94. print "getChooseUIObj option:",option["focus-select"]
  95. if option["focus-select"]["type"].__len__() > 1:
  96. chooseType = option["focus-select"][UATTree.FS_Type]
  97. if chooseType.lower() == "focus":
  98. return self.pyU.getFocusedUIObject()
  99. elif chooseType.lower() == "select":
  100. return self.pyU.getSelectedUIObject()
  101. elif chooseType.lower() == "no":
  102. resId = option[UATTree.TAB_OPTION_VIEW][UATTree.View_ID]
  103. text = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Text]
  104. className = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Class]
  105. desc = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Desc]
  106. return self.pyU.getUiObject(resourceId=resId, text=text, className=className, description=desc)
  107. else:
  108. error(self.cls, "getChooseUIObj", option["name"]+" option focus-select属性配置异常", ERROR)
  109. return None
  110. elif option["focuseView"][UATTree.Focus_Text].__len__() > 0\
  111. or option["focuseView"][UATTree.Focus_ID].__len__() > 1\
  112. or option["focuseView"][UATTree.Focus_Desc].__len__() > 0:
  113. return self.pyU.getUiObject(text=option["focuseView"][UATTree.Focus_Text],
  114. resourceId=option["focuseView"][UATTree.Focus_ID],
  115. description=option["focuseView"][UATTree.Focus_Desc])
  116. else:
  117. error(self.cls, "getChooseUIObj", option["name"] + " option 需要配置 focus-select或者FocusView", ERROR)
  118. return None
  119. '''
  120. 检测parent,在电视上是否被选中了。一个option被选中,表示选中
  121. :param option 数据字典
  122. :return
  123. -3:代表UIView判断未通过;
  124. -2:代表选中了parent,但未找到焦点;
  125. -1:未进入parent的页面,找不到parent layout;
  126. 0:进入了parent的页面,未选中parent;
  127. 1:已经选中parent
  128. '''
  129. def checkParentChoose(self, parent):
  130. debug(self.cls, "checkParentChoose", "parent:" + parent["name"], DEBUG)
  131. chooseTypeDict = {}
  132. layoutResId = parent["layout"][UATTree.Layout_ID]
  133. uiView = parent[UATTree.TAB_UI_VIEW]
  134. uiViewResId = uiView[UATTree.View_ID]
  135. uiViewText = uiView[UATTree.View_Text]
  136. uiViewDesc = uiView[UATTree.View_Desc]
  137. if layoutResId == "" and uiViewResId == "" and uiViewText == "" and uiViewDesc == "":
  138. debug(self.cls, "checkParentChoose", "Warning:Parent %s的Layout resId和UIView信息获取失败!!请注意检查UATree文件!!!"%parent['name'], DEBUG)
  139. return -1
  140. elif layoutResId != "":
  141. # 如果存在UIView信息,则先判断UIView
  142. if uiViewResId != "" or uiViewText != "" or uiViewDesc != "":
  143. isExist = self.checkUIViewExist(uiView)
  144. if isExist is False:
  145. info(self.cls, "checkParentChoose", "当前页面不存在Parent:%s的UIView组件,判断该界面非此parent"%parent['name'], INFO)
  146. return -3
  147. else:
  148. info(self.cls, "checkParentChoose", "已识别出Parent:%s的UIView组件"%parent['name'], INFO)
  149. description = parent["layout"][UATTree.Layout_Desc]
  150. if description != "":
  151. layoutUIObj = self.pyU.getUiObject(resourceId=parent["layout"][UATTree.Layout_ID],
  152. description=parent["layout"][UATTree.Layout_Desc])
  153. else:
  154. layoutUIObj = self.pyU.getUiObject(resourceId=parent["layout"][UATTree.Layout_ID])
  155. if layoutUIObj is None or layoutUIObj.count == 0:
  156. # debug(self.cls, "checkParentChoose", "parent isn't " + parent["name"], DEBUG)
  157. return -1
  158. # print "checkParentChoose, layoutUIObj:",layoutUIObj.info
  159. debug(self.cls, "checkParentChoose", "layoutUIObj:"+str(layoutUIObj.info), DEBUG)
  160. for optionName in parent["option"]:
  161. option = parent["option"][optionName]
  162. if option["focus-select"]["type"].__len__() > 1:
  163. chooseTypeDict[option["focus-select"][UATTree.FS_Type]] = option
  164. elif option["focuseView"][UATTree.Focus_Text].__len__() > 0\
  165. or option["focuseView"][UATTree.Focus_ID].__len__() > 1\
  166. or option["focuseView"][UATTree.Focus_Desc].__len__() > 0:
  167. chooseTypeDict[option["focuseView"][UATTree.Focus_ID]
  168. + option["focuseView"][UATTree.Focus_Text]
  169. + option["focuseView"][UATTree.Focus_Desc]] = option
  170. info(self.cls, "checkParentChoose", str(chooseTypeDict), INFO)
  171. for key in chooseTypeDict.keys():
  172. option = chooseTypeDict[key]
  173. chooseUIObj = self.getChooseUIObj(option)
  174. #TODO 如果选中效果,是没有type[no],例如快捷键,如何处理?
  175. if chooseUIObj is None or chooseUIObj.count == 0:
  176. return -2
  177. debug(self.cls, "checkParentChoose", "chooseUIObj:" + str(chooseUIObj.info), DEBUG)
  178. # 获取到chooseUIObj后,与layout对比坐标,确认焦点是否存在于layout之中
  179. layoutBounds = layoutUIObj.info['bounds']
  180. choosingBounds = chooseUIObj.info['bounds']
  181. if not self.dm.isHasAnotherBounds(layoutBounds, choosingBounds):
  182. info(self.cls, "checkParentChoose",
  183. "识别出parent %s的Layout,但焦点不在该Layout之中,判断界面未处于该parent" % (parent['name']), INFO)
  184. return -2
  185. # 如果该页面text属性不为空,则确认该parent下所有option的text,是否存在于当前页面中;如果text属性为空,则判断index属性
  186. for optionName in parent["option"]:
  187. option = parent["option"][optionName]
  188. # 如果有text属性则确认Text,是否能对比成功
  189. optionText = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Text]
  190. optionId = option[UATTree.TAB_OPTION_VIEW][UATTree.View_ID]
  191. optionIndex = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Index]
  192. if optionText.__len__() >0:
  193. info(self.cls, "checkParentChoose", "checking parent %s text %s"%(parent['name'], optionText), INFO)
  194. textObj = self.pyU.getUiObject(text=optionText)
  195. elif optionId.__len__() >0:
  196. info(self.cls, "checkParentChoose", "checking parent %s optionId %s" % (parent['name'], optionId),
  197. INFO)
  198. textObj = self.pyU.getUiObject(resourceId=optionId)
  199. elif optionIndex != "":
  200. # index属性无法用于判断option,如果在以index属性作为判断依据的页面,则直接返回在这个页面
  201. info(self.cls, "checkParentChoose",
  202. "已找到目标parent %s,该页面为Index item页面,无法判断具体option"%parent['name'], INFO)
  203. return 1
  204. else:
  205. error(self.cls, "checkParentChoose", "当前参数不足以判断option %s是否存在"%(option['name']), ERROR)
  206. continue
  207. if textObj.exists:
  208. info(self.cls, "checkParentChoose",
  209. "已找到目标parent %s,并识别出该parent下的option %s" % (parent['name'], option['name']), INFO)
  210. return 1
  211. else:
  212. info(self.cls, "checkParentChoose",
  213. "return 0" , INFO)
  214. return 0
  215. else:
  216. isExist = self.checkUIViewExist(uiView)
  217. if not isExist:
  218. return -3
  219. else:
  220. info(self.cls, "checkParentChoose",
  221. "识别出parent %s的UIView参数,判断处于该界面中" % (parent['name']), INFO)
  222. return 1
  223. def checkUIViewExist(self, uiView):
  224. resid = uiView[UATTree.View_ID]
  225. text = uiView[UATTree.View_Text]
  226. description = uiView[UATTree.View_Desc]
  227. uiViewObj = self.pyU.getUiObject(resourceId=resid,
  228. text=text,
  229. description=description)
  230. if not uiViewObj.exists:
  231. return False
  232. else:
  233. return True
  234. '''
  235. 检测某个弹窗是否存在。
  236. 弹窗相关的参数放在UIView中配置。
  237. 当存在resId参数时,使用resId获取对象并获取文本,再与text做比较;
  238. 当不存在resId参数时,使用text直接获取对象,判断对象是否存在。
  239. 与checkParentChoose判断不一致,做特殊处理。
  240. '''
  241. def checkDialogExist(self, dialog):
  242. debug(self.cls, "checkDialogExist", "dialog:" + dialog["name"], DEBUG)
  243. dialogText = dialog[UATTree.TAB_UI_VIEW][UATTree.UIView_Text]
  244. dialogResId = dialog[UATTree.TAB_UI_VIEW][UATTree.UIView_ID]
  245. # print "checkDialogExist.dialogText:", dialogText
  246. # print "checkDialogExist.dialogResId:", dialogResId
  247. if dialogResId != "":
  248. textObj = self.pyU.getUiObject(resourceId=dialogResId)
  249. if textObj.exists:
  250. objText = textObj.info['text']
  251. # print "checkDialogExist.objText:", objText
  252. if dialogText in objText:
  253. return 1
  254. else:
  255. return 0
  256. else:
  257. return 0
  258. else:
  259. textObj = self.pyU.getUiObject(text=dialogText)
  260. if textObj.exists:
  261. return 1
  262. else:
  263. return 0
  264. def focusTargetOption(self, parent, option):
  265. if parent[UATTree.TAB_MOVE_KEY][UATTree.Max_Try] != "":
  266. Max_Try = int(parent[UATTree.TAB_MOVE_KEY][UATTree.Max_Try])
  267. else:
  268. Max_Try = parent[UATTree.TAB_OPTION].__len__()
  269. moveKey = parent[UATTree.TAB_MOVE_KEY]
  270. print "moveKey:", moveKey
  271. findDirection = ""
  272. keyType = UATTree.Key_Event
  273. if moveKey[UATTree.Key_Event].__len__() > 1:
  274. findDirection = moveKey[UATTree.Key_Event][0]
  275. keyType = UATTree.Key_Event
  276. elif moveKey[UATTree.Key_IR].__len__() > 1:
  277. findDirection = moveKey[UATTree.Key_IR][0]
  278. keyType = UATTree.Key_IR
  279. elif moveKey[UATTree.Key_Input].__len__() > 1:
  280. inputCmd = moveKey[UATTree.Key_Input]
  281. elif moveKey[UATTree.Key_AM].__len__() > 1:
  282. amCmd = moveKey[UATTree.Key_AM]
  283. else:
  284. error(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " option 读取 move_key失败", ERROR)
  285. return False
  286. chooseType = option[UATTree.TAB_FOCUS_SELECT][UATTree.FS_Type]
  287. optionView = option[UATTree.TAB_OPTION_VIEW]
  288. viewId = optionView[UATTree.View_ID]
  289. viewText = optionView[UATTree.View_Text]
  290. viewIndex = optionView[UATTree.View_Index]
  291. viewClass = optionView[UATTree.View_Class]
  292. viewDesc = optionView[UATTree.View_Desc]
  293. recyclerViewId = parent[UATTree.TAB_LAYOUT][UATTree.Layout_ID]
  294. focuseView = option[UATTree.TAB_FOCUSE_VIEW]
  295. focuseViewId = focuseView[UATTree.View_ID]
  296. others = parent[UATTree.TAB_OTHERS]
  297. hb_keyDict = others[UATTree.Key_HeartBeat]
  298. print "%s chooseType: %s"%(option["name"], chooseType)
  299. if chooseType.__len__() > 1:
  300. if chooseType.lower() == "focus":
  301. if viewText != "" and viewId != "":
  302. info(self.cls, "focusTargetOption", "going toDestFocusByText_with_FocuseResourceId, Option:%s"%option[UATTree.TAB_NAME], INFO)
  303. info(self.cls, "focusTargetOption", "viewText=%s, focuseResId=%s"%(viewText, focuseViewId), INFO)
  304. return self.fm.toDestFocusByText_with_FocuseResourceId(text=viewText,
  305. focuseResId=viewId,
  306. Max_Try=Max_Try,
  307. keyType=keyType,
  308. hb_keyDict=hb_keyDict)
  309. elif viewText != "":
  310. info(self.cls, "focusTargetOption", "going toDestFocusByText_for_RecyclerView, Option:%s"%option[UATTree.TAB_NAME], INFO)
  311. return self.fm.toDestFocusByText_for_RecyclerView(text = viewText,
  312. findDirection = findDirection,
  313. Max_Try = Max_Try,
  314. keyType = keyType,
  315. hb_keyDict=hb_keyDict)
  316. elif viewId != "":
  317. info(self.cls, "focusTargetOption", "going toDestTargetByResourceId_for_RecyclerView, Option:%s"%option[UATTree.TAB_NAME], INFO)
  318. return self.fm.toDestTargetByResourceId_for_RecyclerView(resourceId = viewId,
  319. chooseType = chooseType.lower(),
  320. Max_Try = Max_Try,
  321. keyType = keyType,
  322. hb_keyDict=hb_keyDict)
  323. elif viewDesc != "":
  324. info(self.cls, "focusTargetOption", "going toDestFocusByDescription_for_RecyclerView, Option:%s"%option[UATTree.TAB_NAME], INFO)
  325. return self.fm.toDestFocusByDescription_for_RecyclerView(description=viewDesc,
  326. Max_Try = Max_Try,
  327. keyType = keyType,
  328. hb_keyDict=hb_keyDict)
  329. elif viewIndex != "":
  330. info(self.cls, "focusTargetOption", "going focusItemByIndexFromRecyclerView, Option:%s"%option[UATTree.TAB_NAME], INFO)
  331. return self.fm.focusItemByIndexFromRecyclerView(recyclerView_resId = recyclerViewId,
  332. child_class = viewClass,
  333. target_index = viewIndex,
  334. Max_Try = Max_Try,
  335. keyType = keyType,
  336. hb_keyDict=hb_keyDict)
  337. else:
  338. error(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " option focus-select属性配置异常", ERROR)
  339. return False
  340. elif chooseType.lower() == "select":
  341. if viewText != "":
  342. info(self.cls, "focusTargetOption", "going toDestSelectByText_for_RecyclerView, Option:%s"%option[UATTree.TAB_NAME], INFO)
  343. return self.fm.toDestSelectByText_for_RecyclerView(text = viewText,
  344. optionViewResoucreId = viewId,
  345. listViewResourceId = recyclerViewId,
  346. findDirection = findDirection,
  347. Max_Try = Max_Try,
  348. keyType = keyType,
  349. hb_keyDict=hb_keyDict)
  350. elif viewId != "":
  351. info(self.cls, "focusTargetOption", "going toDestTargetByResourceId_for_RecyclerView, Option:%s"%option[UATTree.TAB_NAME], INFO)
  352. return self.fm.toDestTargetByResourceId_for_RecyclerView(resourceId = viewId,
  353. chooseType = chooseType.lower(),
  354. Max_Try = Max_Try,
  355. keyType = keyType,
  356. hb_keyDict=hb_keyDict)
  357. elif chooseType.lower() == "long_click":
  358. info(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " going to long click type!!!", info)
  359. targetObj = self.pyU.getUiObject(resourceId=viewId)
  360. if targetObj.exists:
  361. info(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " 已找到目标Object,长点击目标Object。", info)
  362. targetObj.long_click()
  363. return True
  364. else:
  365. info(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " 目标Object当前界面未找到!!!", info)
  366. return False
  367. elif chooseType.lower() == "no":
  368. info(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " 目标Object的chooseType为no,默认为不需要选中。", info)
  369. return True
  370. else:
  371. error(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " option focus-select属性配置异常", ERROR)
  372. return False
  373. elif viewText.__len__() > 0\
  374. or focuseViewId.__len__() > 2\
  375. or focuseView[UATTree.Focus_Desc].__len__() > 0:
  376. info(self.cls, "focusTargetOption",
  377. "going toDestFocusByText_for_FocusView, Option:%s" % option[UATTree.TAB_NAME], INFO)
  378. return self.fm.toDestFocusByText_for_FocusView(text = viewText,
  379. FocusViewResourceId = focuseViewId,
  380. findDirection = findDirection,
  381. Max_Try = Max_Try,
  382. keyType = keyType,
  383. hb_keyDict=hb_keyDict)
  384. else:
  385. error(self.cls, "focusTargetOption", "Warning:Option %s读取的参数未能找到合适的执行方式,执行失败,请注意检查UATree文件!!!"%option[UATTree.TAB_NAME], ERROR)
  386. return False
  387. '''
  388. 执行uatree中的各种直接按键,不携带其他参数。限enter_key和toParent_Key。
  389. am和input等带参数的指令,无法处理。
  390. mkey:parent里面的key字典
  391. '''
  392. def executeKey(self, mkey):
  393. eventList = mkey[UATTree.Key_Event]
  394. irList = mkey[UATTree.Key_IR]
  395. print "executeKey,eventList:",eventList
  396. print "executeKey,irList:",irList
  397. times = 1
  398. wait = 0.5
  399. keyList = []
  400. if eventList.__len__() <= 0:
  401. if irList.__len__() <= 0:
  402. info(self.cls, "executeKey", "传入的keyDict中,event和ir的key list均为空!!!默认executeKey执行成功!!!", INFO)
  403. return True
  404. # 读取其中是否存在wait或者times属性
  405. for irKey in irList:
  406. if str(irKey).startswith("times="):
  407. times = int(irKey.lstrip("times="))
  408. if str(irKey).startswith("wait="):
  409. wait = float(irKey.lstrip("wait="))
  410. else:
  411. keyList.append(irKey)
  412. #执行keyList
  413. info(self.cls, "executeKey", "executing irKey, wait=%s, times=%s"%(wait, times), INFO)
  414. for i in range(0, times):
  415. for irKey in keyList:
  416. print "executeKey, sendKey:%s"%irKey
  417. self.tvOperator.sendKey(irKey, duration=wait)
  418. else:
  419. # 读取其中是否存在wait或者times属性
  420. for eventKey in eventList:
  421. if str(eventKey).startswith("times="):
  422. times = int(eventKey.lstrip("times="))
  423. if str(eventKey).startswith("wait="):
  424. wait = float(eventKey.lstrip("wait="))
  425. else:
  426. keyList.append(eventKey)
  427. #执行keyList
  428. info(self.cls, "executeKey", "executing eventKey, wait=%s, times=%s"%(wait, times), INFO)
  429. for i in range(0, times):
  430. for eventKey in keyList:
  431. print "executeKey, pressKeyTimes:%s"%eventKey
  432. if self.eventKeyCode.has_key(eventKey.upper()):
  433. keyCode = self.eventKeyCode[eventKey.upper()]
  434. info(self.cls, "executeKey", "eventKeyCode has key %s, code is %s" % (eventKey, keyCode), INFO)
  435. self.pyU.pressKeyTimes(keyCode)
  436. else:
  437. self.pyU.pressKeyTimes(eventKey)
  438. time.sleep(wait)
  439. return True
  440. '''
  441. 执行uatree中的moveKey
  442. :param mkey move_key的字典
  443. flag 决定执行的方向,传入值为0和1
  444. '''
  445. def executeMoveKey(self, mkey, flag):
  446. eventList = mkey[UATTree.Key_Event]
  447. irList = mkey[UATTree.Key_IR]
  448. print "executeMoveKey,eventList:",eventList
  449. print "executeMoveKey,irList:",irList
  450. times = 1
  451. wait = 0.5
  452. if eventList.__len__() <= 0:
  453. if irList.__len__() <= 0:
  454. return False
  455. # 读取其中是否存在wait或者times属性
  456. for item in irList:
  457. if str(item).startswith("times="):
  458. times = int(item.lstrip("times="))
  459. irList.remove(item)
  460. if str(item).startswith("wait="):
  461. wait = float(item.lstrip("wait="))
  462. irList.remove(item)
  463. #执行move_key
  464. info(self.cls, "executeMoveKey", "executing irMoveKey:%s, wait=%s, times=%s, flag=%s"%(irList[flag],wait, times, flag), INFO)
  465. return self.tvOperator.sendKey(irList[flag], duration=wait)
  466. else:
  467. # 读取其中是否存在wait或者times属性
  468. for item in eventList:
  469. if str(item).startswith("times="):
  470. times = int(item.lstrip("times="))
  471. eventList.remove(item)
  472. if str(item).startswith("wait="):
  473. wait = float(item.lstrip("wait="))
  474. eventList.remove(item)
  475. #执行move_key
  476. info(self.cls, "executeMoveKey", "executing eventMoveKey:%s, wait=%s, times=%s, flag=%s"%(eventList[flag], wait, times, flag), INFO)
  477. self.pyU.pressKeyTimes(eventList[flag])
  478. time.sleep(wait)
  479. # pressKeyTimes不返回Bool结果
  480. return True
  481. '''
  482. 根据keyType执行key值
  483. '''
  484. def executeKeyByType(self, key, keyType, times = 1, duration = 1.0):
  485. if keyType == UATTree.Key_Event:
  486. if self.eventKeyCode.has_key(key.upper()):
  487. keyCode = self.eventKeyCode[key.upper()]
  488. info(self.cls, "executeKeyByType", "eventKeyCode has key %s, code is %s" % (key, keyCode), INFO)
  489. self.pyU.pressKeyTimes(keyCode, times, duration)
  490. else:
  491. self.pyU.pressKeyTimes(key, times, duration)
  492. return True
  493. elif keyType == UATTree.Key_IR:
  494. self.tvOperator.sendKey(key, times, duration)
  495. return True
  496. else:
  497. return False
  498. '''
  499. 执行firstParent的shortCut_key
  500. '''
  501. def executeShortCutKey(self, parent):
  502. amList = str(parent[UATTree.TAB_SHORTCUT_KEY][UATTree.Key_AM]).split(",")
  503. waitTime = 0
  504. print "amList:", amList
  505. if amList[-1].startswith("wait="):
  506. waitTime = float(amList[-1].lstrip("wait="))
  507. print "executing ShortCutKey,amWaitTime:",waitTime
  508. if amList[0].lower() == "activity":
  509. print "executeShortCutKey,amList:",amList,parent[UATTree.TAB_UI_VIEW]
  510. activityParam = parent[UATTree.TAB_UI_VIEW][UATTree.UIView_Activity]
  511. # 通过 / 号分割pkgName和activity,部分项目不存在activity。
  512. pkgList = string_util.strToList(activityParam,"/")
  513. pkgName = pkgList[0]
  514. if pkgList.__len__() == 1:
  515. self.pyU.startApp(pkgName)
  516. elif pkgList.__len__() == 2:
  517. activity = pkgList[1]
  518. self.pyU.startApp(pkgName, activity)
  519. else:
  520. debug(self.cls, "executeShortCutKey", "UATree中 %s activity参数异常!!请检查!!"%parent[UATTree.TAB_NAME], DEBUG)
  521. time.sleep(waitTime)
  522. return True
  523. else:
  524. return self.executeKey(parent[UATTree.TAB_SHORTCUT_KEY])
  525. '''
  526. 用于处理parent可能出现的弹窗,isForword用于判断是处理进入弹窗还是退出弹窗
  527. '''
  528. def executeDialog(self, parent, isForward=True):
  529. print "parent %s executeDialog parent[UATTree.TAB_UI_VIEW]:%s"%(parent[UATTree.TAB_NAME], parent[UATTree.TAB_UI_VIEW])
  530. if isForward is True:
  531. dialog_A = parent[UATTree.TAB_UI_VIEW][UATTree.UIView_Dialog_F]
  532. type = "forward"
  533. else:
  534. dialog_A = parent[UATTree.TAB_UI_VIEW][UATTree.UIView_Dialog_B]
  535. type = "back"
  536. if dialog_A.__len__ > 0:
  537. info(self.cls, "executeDialog", "parent %s has %s dialog:%s"%(parent[UATTree.TAB_NAME], type, dialog_A), INFO)
  538. for dialogName in dialog_A:
  539. dialog = dialog_A[dialogName]
  540. ret = self.checkDialogExist(dialog)
  541. if ret < 1:
  542. info(self.cls, "executeDialog", "parent %s dialog %s doesnt popup."%(parent[UATTree.TAB_NAME], dialogName), INFO)
  543. continue
  544. tarOption = dialog["choose"]
  545. if not self.focusTargetOption(dialog, tarOption):
  546. error(self.cls, "executeDialog", "dialog %s focus choose option %s fail"%(dialogName, tarOption), ERROR)
  547. return 0
  548. print "executing enter_key"
  549. self.executeKey(tarOption[UATTree.TAB_ENTER_KEY])
  550. time.sleep(1)
  551. # 考虑到弹窗优先级与遍历顺序可能不一致的问题,重新再进行一次弹窗遍历
  552. return self.executeDialog(parent, isForward)
  553. else:
  554. info(self.cls, "executeDialog", "parent %s has no %s dialog"%(parent[UATTree.TAB_NAME], type), INFO)
  555. return 1
  556. '''
  557. 执行设值动作,区分数字设值以及非数字设值
  558. '''
  559. def setValue(self, option, value):
  560. textValue = option[UATTree.TAB_TEXT_VALUE]
  561. info(self.cls, "setValue", "textValue:%s"%textValue, INFO)
  562. if textValue[UATTree.ValueView_Value] != "":
  563. enterKey = option[UATTree.TAB_ENTER_KEY]
  564. if enterKey[UATTree.Key_Event] != "":
  565. keyList = enterKey[UATTree.Key_Event]
  566. keyType = UATTree.Key_Event
  567. elif enterKey[UATTree.Key_IR] != "":
  568. keyList = enterKey[UATTree.Key_IR]
  569. keyType = UATTree.Key_IR
  570. else:
  571. info(self.cls, "setValue", "textValue在有值的情况下,enterKey读取失败,无法进行setValue的动作。", INFO)
  572. return False
  573. if textValue.has_key(UATTree.ValueView_Min) and textValue.has_key(UATTree.ValueView_Max):
  574. valueViewResId = textValue[UATTree.ValueView_ID]
  575. count = 0
  576. # 默认步长为1
  577. stepSize = 1.0
  578. if textValue[UATTree.ValueView_StepSize] != "":
  579. stepSize = float(textValue[UATTree.ValueView_StepSize])
  580. # 默认设值间隔为0.2s
  581. duration = 0.2
  582. if textValue[UATTree.ValueView_Duration] != "":
  583. duration = float(textValue[UATTree.ValueView_Duration])
  584. info(self.cls, "setValue", "stepSize:%s, duration:%s"%(stepSize, duration), INFO)
  585. while(count < 3):
  586. # 获取数值时存在两种情况,一种是数值文本在聚焦组件里,一种在聚焦组件之外,分别处理。
  587. # 先在聚焦组件内找数值
  588. choosedObj = self.getChooseUIObj(option)
  589. print "choosedObj.info:", choosedObj.info
  590. text = self.getValueInObjectByTextResourceId(choosedObj, valueViewResId)
  591. if text is None:
  592. # 组件之中找不到时,则直接用resourceId在整个页面找
  593. text = self.getValueByTextResourceId(valueViewResId)
  594. if text is None:
  595. error(self.cls, "setValue", "获取数值失败,请检查%s 的textValue resid是否正确"%option[UATTree.TAB_NAME], ERROR)
  596. return False
  597. info(self.cls, "setValue", "当前设值为%s"%text, INFO)
  598. text_num = float(text)
  599. value_num = float(value)
  600. if text_num is None:
  601. return False
  602. if value_num < text_num:
  603. self.executeKeyByType(keyList[0], keyType, int((text_num - value_num)/stepSize), duration)
  604. elif value_num > text_num:
  605. self.executeKeyByType(keyList[1], keyType, int((value_num - text_num)/stepSize), duration)
  606. else:
  607. return True
  608. count += 1
  609. else:
  610. info(self.cls, "setValue", "%s次设值仍未能设置为%s,设值失败"%(count+1, value), INFO)
  611. return False
  612. elif textValue[UATTree.ValueView_Value].lower() == "input":
  613. info(self.cls, "setValue", "设值类型为input类型,传入的值为%s"%value, INFO)
  614. # 设值类型必须要有设值textBox Object
  615. resid = textValue[UATTree.ValueView_ID]
  616. text = textValue[UATTree.ValueView_Text]
  617. desc = textValue[UATTree.ValueView_Desc]
  618. textBoxObj = self.pyU.getUiObject(resourceId=resid, text=text, description=desc)
  619. if not textBoxObj.exists:
  620. debug(self.cls, "setValue", "未能获取到设值的TextBox Object!!!请检查相关配置是否能获取到TextBox!!!", DEBUG)
  621. return False
  622. setValueSuccess = textBoxObj.set_text(value)
  623. if not setValueSuccess:
  624. debug(self.cls, "setValue", "TextBox使用set_text()接口设值失败,值为%s"%value, DEBUG)
  625. return False
  626. else:
  627. print "executing enter_key"
  628. return self.executeKey(option[UATTree.TAB_ENTER_KEY])
  629. else:
  630. info(self.cls, "setValue", "读取到value参数配置为非数值value,开始进行非数值型value设值。", INFO)
  631. try:
  632. valueView = textValue[value]
  633. valueViewText = valueView["text"]
  634. valueViewResId = valueView["resid"]
  635. except Exception,e:
  636. info(self.cls, "setValue", "value %s的配置信息读取失败!!!设值失败!!!请确保该value的text属性和resid属性均已按格式配好!!!"%value, INFO)
  637. return False
  638. Max_Try = textValue[UATTree.ValueView_Value].__len__()
  639. count = 0
  640. reverse_count = 0
  641. while (True):
  642. # 获取当前值时存在两种情况,一种是数值文本在聚焦组件里,一种在聚焦组件之外,分别处理。
  643. # 先在聚焦组件内找当前值
  644. choosedObj = self.getChooseUIObj(option)
  645. print "choosedObj.info:", choosedObj.info
  646. for i in range(choosedObj.info["childCount"]):
  647. childUIObject = choosedObj.child_by_instance(i, resourceId=valueViewResId)
  648. if childUIObject.exists:
  649. text = childUIObject.info['text']
  650. break
  651. else:
  652. # 组件之中找不到时,则直接用resourceId在整个页面找
  653. text = self.getValueByTextResourceId(valueViewResId)
  654. if text is None:
  655. error(self.cls, "setValue", "获取数值失败,请检查%s 的textValue resid是否正确" % option[UATTree.TAB_NAME],
  656. ERROR)
  657. return False
  658. info(self.cls, "setValue", "当前设值为%s" % text, INFO)
  659. if text == valueViewText:
  660. info(self.cls, "setValue",
  661. "option %s设值为 %s 成功!!!"%(option[UATTree.TAB_NAME], value), INFO)
  662. return True
  663. if count < Max_Try:
  664. self.executeKeyByType(keyList[0], keyType)
  665. count += 1
  666. elif reverse_count < Max_Try:
  667. self.executeKeyByType(keyList[1], keyType)
  668. reverse_count += 1
  669. else:
  670. info(self.cls, "setValue",
  671. "option %s设值已经尝试最大次数%s次,未能切换至目标value %s"%(option[UATTree.TAB_NAME], Max_Try, value) % value, INFO)
  672. return False
  673. else:
  674. optionName = value
  675. option = self.uatPathManage.uatData.getOption(optionName)
  676. parent = self.uatPathManage.uatData.getParentByOption(option)
  677. ret = self.focusTargetOption(parent, option)
  678. if not ret:
  679. info(self.cls, "setValue", "未能聚焦至目标value %s,设值失败"%value, INFO)
  680. return False
  681. info(self.cls, "setValue", "已聚焦至目标value %s"%value, INFO)
  682. print "executing enter_key"
  683. self.executeKey(option[UATTree.TAB_ENTER_KEY])
  684. return True
  685. '''
  686. 根据传入路径进行退出菜单的动作。
  687. 顺着传入的parent path,逐个确认当前页面是否为该parent。如果不是该parent,则往path后面继续遍历;如果是该parent,则执行该层parent的toParentKey
  688. '''
  689. def exitMenuByPath(self, path):
  690. # print "exitMenuByPath path:", path
  691. for i in range(0, path.__len__()):
  692. parent = path[i]
  693. info(self.cls, "exitMenuByPath", "check parent:%s"%parent[UATTree.TAB_NAME], INFO)
  694. ret = self.checkParentChoose(parent)
  695. if ret < 1:
  696. continue
  697. toParentKey = parent[UATTree.TAB_TOPARENT_KEY]
  698. info(self.cls, "exitMenuByPath", "now is in parent:%s"%parent[UATTree.TAB_NAME], INFO)
  699. if toParentKey[UATTree.Key_Event] == [] and toParentKey[UATTree.Key_IR] == []:
  700. info(self.cls, "exitMenuByPath", "parent:%s has no toparent_key, using default back" % parent[UATTree.TAB_NAME], INFO)
  701. self.executeKeyByType("back", UATTree.Key_Event)
  702. else:
  703. self.executeKey(toParentKey)
  704. time.sleep(1)
  705. ret = self.executeDialog(parent, False)
  706. if ret < 1:
  707. return False
  708. return True
  709. def getUIObjPic(self, obj):
  710. picName = time.time()
  711. picPath = os.path.join(getSATTmpDIR(), "%s.png"%picName)
  712. if obj == None:
  713. return False, picPath, ""
  714. self.CC.takePicture(picPath)
  715. try:
  716. bounds = obj.info["bounds"]
  717. area = [bounds["left"], bounds["top"], bounds["right"], bounds["bottom"]]
  718. cutPicPath = os.path.join(getSATTmpDIR(), "%s_cutPic_%s.png"%(picName, area))
  719. self.imgCMP.saveCropPic(picPath, cutPicPath, area)
  720. except Exception,e:
  721. return False, picPath, ""
  722. return True, picPath, cutPicPath
  723. def infoViewCmpText(self, cmpText, picPath):
  724. ocrParamList = [("ENG_CHN", 10000),
  725. ("ENG_CHN", 10001)]
  726. for ocrParam in ocrParamList:
  727. ocr_str = self.ocrConvert.getStr(picPath, ocrParam[0], ocrParam[1])
  728. info(self.cls, "infoViewCmpText", "cmpText:%s ocr_str:%s ocrParam:%s"%(cmpText, ocr_str, ocrParam),INFO)
  729. if strcmp(ocr_str, cmpText):
  730. info(self.cls, "infoViewCmpText", "OCR文字识别对比成功",INFO)
  731. return 1
  732. else:
  733. error(self.cls, "infoViewCmpText", "Waring:OCR文字识别对比失败!!",ERROR)
  734. return 0
  735. def infoViewCmpPic(self, cmpPic, picPath):
  736. cmpImg = cv.imread(cmpPic)
  737. cutImg = cv.imread(picPath)
  738. result = self.imgCMP.cmpImgTotal(cmpImg, cutImg)
  739. if result is True:
  740. info(self.cls, "infoViewCmpText", "图片对比成功", INFO)
  741. return 1
  742. else:
  743. error(self.cls, "infoViewCmpText", "Waring:图片对比失败!!",ERROR)
  744. return 0
  745. def getValueByTextResourceId(self, textResourceId):
  746. try:
  747. textObj = self.pyU.getUiObject(resourceId=textResourceId)
  748. text = textObj.info['text']
  749. digitList = getDigitFromString(text)
  750. return digitList[-1]
  751. except Exception, e:
  752. return None
  753. def getValueInObjectByTextResourceId(self, object, textResourceId):
  754. try:
  755. for i in range(object.info["childCount"]):
  756. childUIObject = object.child_by_instance(i, resourceId=textResourceId)
  757. if childUIObject.exists:
  758. text = childUIObject.info['text']
  759. digitList = getDigitFromString(text)
  760. return digitList[-1]
  761. else:
  762. return None
  763. except Exception, e:
  764. error(self.cls, "getValueInObjectByTextResourceId", "getValueInObjectByByTextResourceId:Object loading error!!!!!!error msg:%s"%e, ERROR)
  765. return None