123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- # -*- coding:utf-8 -*-
- from UAT_PathManage import UATPathManage
- from ssat_sdk.UATree.UAT_tree import UATTree
- from ssat_sdk.UATree.UAT_treeConstant import TreeConst
- from UAT_runnerCommand import UATRunnerCommand
- from ssat_sdk.python_uiautomator import PyUIAutomator, FocusManageAndroid, DirectionManageAndroid
- from UAT_log import error, debug, info
- import os, sys, time
- DEBUG = True
- INFO =True
- ERROR = True
- class UATRunner():
- cls = "UATRunner"
- def __init__(self):
- self.uatPathManage = UATPathManage()
- self.pyU = PyUIAutomator()
- self.dm = DirectionManageAndroid()
- self.fm = FocusManageAndroid(self.pyU, self.dm)
- self.runnerCmd = UATRunnerCommand(self.uatPathManage, self.pyU, self.dm, self.fm)
- # setOptionValue之后需要一个退回的pathlist来退出菜单
- self.executedPath = []
- '''
- 当电视重启以后,uiautomator连接会断开,需要重新赋予UATRunner一个可用的连接对象
- '''
- def rebuildUiAutomator(self, pyUIAutomator, directionManageAndroid, focusManageAndroid):
- self.pyU = pyUIAutomator
- self.dm = directionManageAndroid
- self.fm = focusManageAndroid
- self.runnerCmd = UATRunnerCommand(self.uatPathManage, self.pyU, self.dm, self.fm)
- '''
- 返回option的object
- '''
- def getOptionObject(self, option):
- className = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Class]
- desc = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Desc]
- resId = option[UATTree.TAB_OPTION_VIEW][UATTree.View_ID]
- text = option[UATTree.TAB_OPTION_VIEW][UATTree.View_Text]
- return self.pyU.getUiObject(className=className, resourceId=resId, description=desc, text=text)
- '''
- 根据parent的layout和一个option判断在 UATree中的哪个界面,或者还没有进入UATree界面中
- :param option:目标option,表示在focusOption的路径上寻找界面定位。则根据excel分表查找
- :return parent数据,或者None。None代表未进入UATree界面中
- '''
- def locateParentUI(self, option=None):
- reg = ""
- if option is not None:
- print "locateParentUI,option:",option[UATTree.TAB_NAME]
- oname = option[UATTree.TAB_NAME]
- reg = oname.split("_")[0]
- print "locateParentUI,reg=",reg
- cparent = None
- treeDict = self.uatPathManage.uatData.getTreeDict()
- # print "locateParentUI: treeDict levels:",treeDict.keys()
- parentList = []
- levelList = treeDict.keys()
- flag = False
- for index in range(levelList.__len__()-1, -1, -1):
- level = levelList[index]
- # print "locateParentUI,level:", index, level
- levelDict = treeDict[level]
- for parent in levelDict:
- if reg.__len__() >0 and not parent.startswith(reg):
- continue
- parentDict = levelDict[parent]
- layout = parentDict["layout"]
- # print "locateParentUI: layout:", layout
- ret = self.runnerCmd.checkParentChoose(parentDict)
- if ret > 0:
- cparent = parentDict
- flag = True
- break
- if flag == True:
- break
- if cparent is None:
- info(self.cls, "locateParentUI", "没有选中Parent,电视界面不知道在哪里", INFO)
- else:
- info(self.cls, "locateParentUI", "选中Parent:" + cparent[UATTree.TAB_NAME], INFO)
- print "ParentParam:", cparent
- return cparent
- '''
- 在该option所在页面下,聚焦到目标option
- '''
- def moveToOption(self, option):
- parent = self.uatPathManage.uatData.getParentByOption(option)
- return self.runnerCmd.focusTargetOption(parent, option)
- '''
- :return -1 执行失败,放弃重新定位执行;0 执行失败,重新定位执行; 1 执行成功
- '''
- def runForwardPath(self, backPath, forwardPath):
- fLen = forwardPath.__len__()
- fParent = forwardPath[fLen-1]
- # 当backPath和forwardPath的父交点为first层时,不能走shortcut_key,否则会导致执行出现问题(USB界面)
- if fParent[UATTree.TAB_LEVEL] == "first" \
- and backPath.__len__() < 2:
- ret = self.openFirstParent(fParent, forwardPath)
- if ret < 1: #注意打开firstparent界面成功,定位错误,会重新定位。场景:usb
- return ret
- # 逐步进入后面的parent页面
- else:
- ret = self.goMidPath(fParent, forwardPath[1: fLen- 1])
- if ret is False:
- return -1
- #在目标parent中,选中目标option
- return self.moveToOption(forwardPath[0])
- else:
- ret = self.goMidPath(forwardPath[fLen - 1], forwardPath[1:fLen - 1])
- if ret is False:
- return -1
- # 在目标parent中,选中目标option
- return self.moveToOption(forwardPath[0])
- '''
- 打开第一个页面
- :return: -1 代表activity打开失败,0 代表activity打开成功,焦点不在parent layout中;1 表示页面打开成功,焦点在parent layout中
- -2 表示处理弹窗的过程中失败了
- '''
- def openFirstParent(self, fParent, forwardPath):
- info(self.cls, "openFirstParent", "GOTO first parent " + fParent[UATTree.TAB_NAME], INFO)
- flag = self.runnerCmd.executeShortCutKey(fParent)
- if flag is False:
- error(self.cls, "openFirstParent", "Open first parent%s fail."%(fParent[UATTree.TAB_NAME]), ERROR)
- return -1
- ret = self.runnerCmd.executeDialog(fParent)
- if ret < 1:
- return -2
- flag1 = self.runnerCmd.checkParentChoose(fParent)
- if flag1 < 1:
- error(self.cls, "openFirstParent", "Open first parent activity.But parent %s not foucsed." % (fParent[UATTree.TAB_NAME]), ERROR)
- return 0
- return 1
- def goMidPath(self, curParent, midParentList):
- mLen = midParentList.__len__()
- for index in range(mLen-1, -1, -1):
- parent = midParentList[index]
- info(self.cls, "goMidPath", "GOTO parent %s from parent %s "%(parent[UATTree.TAB_NAME], curParent[UATTree.TAB_NAME]), INFO)
- ret = self.gotoNextParent(curParent, parent, midParentList)
- if ret == 0:
- return False
- curParent = parent
- return True
- '''
- :return 0:代表失败;1代表enterKey发送成功,进入下一个界面
- '''
- def gotoNextParent(self, curParent, targetParent, parentList):
- targetOptionName = targetParent[UATTree.TAB_NAME]
- targetOption = curParent[UATTree.TAB_OPTION][targetOptionName]
- flag = self.moveToOption(targetOption)
- if flag is False:
- return 0
- info(self.cls, "gotoNextParent", "moveToOption:%s done! executing enter key!"%targetOption[UATTree.TAB_NAME], INFO)
- ret = self.runnerCmd.executeEnterKey(targetOption[UATTree.TAB_ENTER_KEY], nextParent=targetParent)
- if ret is False:
- error(self.cls, "gotoNextParent",
- "Send parent %s enter key fail." % (curParent[UATTree.TAB_NAME]), ERROR)
- return 0
- else:
- ret = self.runnerCmd.executeDialog(targetParent)
- return ret
- '''
- 执行backPath
- :return true成功,false失败
- '''
- def runBackPath(self, backPath):
- bLen = backPath.__len__()
- if bLen <= 1:
- return False
- if bLen == 2:
- return True
- for index in range(1, bLen-1):
- curParent = backPath[index]
- prevParent = backPath[index+1]
- info(self.cls, "runBackPath", "back to parent %s from parent %s."
- %(backPath[index][UATTree.TAB_NAME], backPath[index+1][UATTree.TAB_NAME]), INFO)
- flag = self.backToPrevParent(curParent, prevParent)
- if flag is False:
- return False
- return True
- def backToPrevParent(self, curParent, targetParent):
- backKeys = curParent[UATTree.TAB_TOPARENT_KEY]
- self.runnerCmd.executeKey(backKeys)
- dialog_A = curParent[UATTree.TAB_UI_VIEW][UATTree.UIView_Dialog_B]
- if dialog_A.__len__() > 0:
- ret = self.runnerCmd.executeDialog(curParent, isForward=False)
- if ret == 0:
- return False
- flag = self.runnerCmd.checkParentChoose(targetParent)
- if flag < 1:
- error(self.cls, "backToPrevParent",
- "back to parent %s from parent %s fail." % (targetParent[UATTree.TAB_NAME], curParent[UATTree.TAB_NAME]), ERROR)
- return False
- return True
- '''
- fromFirst:表示是否指定从FirstParent打开开始路径执行。
- count:递归控制变量,执行路径的最大尝试次数
- '''
- def focusOption(self, option, fromFirst, count = 0):
- info(self.cls, "focusOption", "fromFirst:"+str(fromFirst), INFO)
- if fromFirst is True:
- curParent = None
- else:
- curParent = self.locateParentUI(option)
- backPath,forwardPath = self.uatPathManage.genOptionSmartPath(curParent, option)
- info(self.cls,"focusOption", "backPath:", INFO)
- self.uatPathManage.info(backPath)
- info(self.cls,"focusOption", "forwardPath:", INFO)
- self.uatPathManage.info(forwardPath)
- if forwardPath.__len__() == 0:
- return False
- if backPath.__len__() == 0 and forwardPath.__len__() >= 2:
- info(self.cls, "focusOption", "runBackPath success", INFO)
- ret = self.runForwardPath(backPath, forwardPath)
- self.executedPath = self.getExecutedPath(forwardPath)
- if ret ==0: #重新计算路径执行
- if count < 3:
- return self.focusOption(option, fromFirst, count+1)
- else:
- info(self.cls, "focusOption", "runForwardPath fail %s times, focusOption Fail!!!"%count, INFO)
- return False
- if backPath.__len__() >= 2 and forwardPath.__len__() >=2:
- backFlag = self.runBackPath(backPath)
- if backFlag is False:
- info(self.cls, "focusOption", "runBackPath fail", INFO)
- return False
- info(self.cls, "focusOption", "runBackPath success", INFO)
- goFlag = self.runForwardPath(backPath, forwardPath)
- self.executedPath = self.getExecutedPath(forwardPath)
- if goFlag < 1:
- info(self.cls, "focusOption", "runForwardPath fail", INFO)
- return False
- info(self.cls, "focusOption", "runForwardPath success", INFO)
- return True
- '''
- 回退路径,仅仅只是使用forwardPath的话,最后一个元素是option,但是实际上已经进入了这个界面,应该判断的是parent。
- 所以要把forwardPath里面的option替换为parent;如果没有配这个option对应的parent,则去掉该option,以便exitMenuByPath函数使用。
- '''
- def getExecutedPath(self, forwardPath):
- option = forwardPath[0]
- parentName = option[UATTree.TAB_NAME]
- parent = self.uatPathManage.uatData.getParentDict(parentName)
- if parent is None:
- forwardPath.remove(option)
- else:
- forwardPath[0] = parent
- return forwardPath
- '''
- 执行该option的EnterKey
- '''
- def sendOptionEnterKey(self, option):
- enterKey = option[UATTree.TAB_ENTER_KEY]
- return self.runnerCmd.executeEnterKey(enterKey)
- '''
- 检查当前页面是否存在目标option
- '''
- def checkOptionExist(self, option):
- parent = self.uatPathManage.uatData.getParentByOption(option)
- if not self.runnerCmd.checkParentChoose(parent):
- return False
- return self.runnerCmd.checkOptionExist(option, parent)
- '''
- 在focusOption基础上,执行目标option的enter_key
- '''
- def openOption(self, option, fromFirst, nextParent = None):
- info(self.cls, "openOption", "OptionName:"+option[UATTree.TAB_NAME], INFO)
- ret = self.focusOption(option, fromFirst)
- if ret is False:
- return False
- ret = self.runnerCmd.executeEnterKey(option[UATTree.TAB_ENTER_KEY],nextParent)
- info(self.cls, "openOption", "executeKey,ret:%s"%ret, INFO)
- parent = self.uatPathManage.uatData.getParentDict(option[UATTree.TAB_NAME])
- if parent is None:
- return ret
- else:
- return self.runnerCmd.executeDialog(parent)
- def openParent(self, parent, fromFirst):
- if parent[UATTree.TAB_LEVEL] == 'first':
- return self.openFirstParent(parent, "")
- else:
- prevOption = self.uatPathManage.uatData.getOption(parent[UATTree.TAB_NAME])
- return self.openOption(prevOption, fromFirst, nextParent=parent)
- def setOptionValue(self, option, value, exitMenu=True, fromFirst=True):
- ret = self.openOption(option, fromFirst)
- if ret is False:
- info(self.cls, "setOptionValue", "openOption过程执行失败!!!", INFO)
- if exitMenu is True:
- self.runnerCmd.exitMenuByPath(self.executedPath)
- return False
- ret1 = self.runnerCmd.setValue(option, value)
- if exitMenu is True:
- ret2 = self.runnerCmd.exitMenuByPath(self.executedPath)
- else:
- ret2 = True
- return (ret1 and ret2)
- def checkOptionInfoView(self, option, cmpText = "", cmpPic = ""):
- infoObj = self.getOptionInfoView(option)
- result, picPath, cutPicPath = self.runnerCmd.getUIObjPic(infoObj)
- if result is False:
- error(self.cls, "checkOptionInfoView", "Warning:option %s 截取infoView所在坐标图片失败!!!" % option["name"], ERROR)
- return -1, picPath, cutPicPath
- if cmpPic != "":
- result = self.runnerCmd.infoViewCmpPic(cmpPic, cutPicPath)
- return result, picPath, cutPicPath
- elif cmpText != "":
- result = self.runnerCmd.infoViewCmpText(cmpText, cutPicPath)
- return result, picPath, cutPicPath
- else:
- info(self.cls, "checkOptionInfoView", "未传入cmpText和cmpPic参数,仅检查infoView是否存在", INFO)
- if infoObj is None:
- error(self.cls, "checkOptionInfoView", "Warning:option %s 获取infoView失败!!!" % option["name"],
- ERROR)
- return -1, picPath, cutPicPath
- else:
- info(self.cls, "checkOptionInfoView", "已识别到option %s的infoView" % option["name"], INFO)
- return 1, picPath, cutPicPath
- def getOptionInfoView(self, option):
- optionView = option[UATTree.TAB_INFO_VIEW]
- viewId = optionView[UATTree.View_ID]
- viewText = optionView[UATTree.View_Text]
- viewDesc = optionView[UATTree.View_Desc]
- viewClass = optionView[UATTree.View_Class]
- if viewId.__len__() == 0:
- return None
- infoObj = self.pyU.getUiObject(resourceId=viewId, text=viewText, className=viewClass, description=viewDesc)
- return infoObj
- if __name__ == "__main__":
- uatRunner = UATRunner()
- option = uatRunner.uatPathManage.uatData.getOption("usb_video_h264-ac3")
- uatRunner.openOption(option, False)
- # print uatRunner.locateParentUI()
- # parent = uatRunner.uatPathManage.uatData.getParentDict("usb_bmp")
- # uatRunner.runnerCmd.checkParentChoose(parent)
- # print option
- # option = uatRunner.uatPathManage.uatData.getOption("usb_aac_option")
- # cmpPic = r"D:/SAT/tmp\1572432282.74_cutPic_[932, 548, 1812, 597].png"
- # result, picpath, cutPicPath = uatRunner.checkOptionInfoView(option, cmpPic=cmpPic)
- # uatRunner.moveToOption(option)
- # parent = uatRunner.locateParentUI()
- # print "locateParentUI,parent:", parent
- # option = uatRunner.uatPathManage.uatData.getOption("usb_brightness")
- # print uatRunner.setOptionValue(option, 50)
|