|
@@ -81,7 +81,7 @@ class COptionAction(CBaseLog):
|
|
|
# ==============常用对象数据==============;
|
|
|
self.__optionPaths = self.__optionExcel.getOptionPaths(self.__optionName)
|
|
|
# 如果__optionValue空则不取value表任何内容;
|
|
|
- if self.__optionValue != "":
|
|
|
+ if self.__optionValue != "" or self.__optionValue is not None:
|
|
|
self.__optionValueInfo = self.__optionExcel.getOptionValueInfo(self.__optionName, self.__optionValue)
|
|
|
self.__optionInfo = self.__optionExcel.getOptionInfo(self.__optionName)
|
|
|
# 当前状态下的变量,与__pos对应;
|
|
@@ -92,8 +92,8 @@ class COptionAction(CBaseLog):
|
|
|
# 获取一次当前层级信息;
|
|
|
self.getCurOptionInfo()
|
|
|
# 相关返回操作;
|
|
|
- self.__isEnterKeyInValue = False # 节点在value表时,是否发送enter key.
|
|
|
- self.__valueType = VType.SelectType # 节点在value表时,value值的类型(0:选择型, 1:输入型,2:range()数值型。)
|
|
|
+ self.__isEnterKeyInValue = False # 节点在value表时,是否发送enter key.
|
|
|
+ self.__valueType = VType.SelectType # 节点在value表时,value值的类型(0:选择型, 1:输入型,2:range()数值型。)
|
|
|
|
|
|
@property
|
|
|
def pos(self):
|
|
@@ -116,7 +116,7 @@ class COptionAction(CBaseLog):
|
|
|
return self.__optionValueInfo
|
|
|
|
|
|
'''
|
|
|
- 函数:截图并返回截图路径;
|
|
|
+ 函数:截图并返回截图路径,如果当前option/optionValue含有layout坐标参数,则返回坐标截图;
|
|
|
参数:无
|
|
|
返回:截图路径;
|
|
|
'''
|
|
@@ -126,7 +126,24 @@ class COptionAction(CBaseLog):
|
|
|
COptionAction.__captureCard.takePicture(img)
|
|
|
if not os.path.exists(img):
|
|
|
self.error(u"截图失败:%s" % img)
|
|
|
- return img
|
|
|
+ retImg = img
|
|
|
+ # 判断当前处于option层还是value层
|
|
|
+ if self.__pos >= self.__optionPaths.__len__():
|
|
|
+ curInfo = self.__optionValueInfo
|
|
|
+ else:
|
|
|
+ curInfo = self.__curOptionInfo
|
|
|
+
|
|
|
+ # 判断当前层是否存在layout参数
|
|
|
+ if "layout" in curInfo and 'bounds' in curInfo['layout']:
|
|
|
+ if curInfo['layout']['bounds'] is "":
|
|
|
+ self.info("当前option未配置layout参数")
|
|
|
+ elif curInfo['layout']['bounds'].__len__() != 4:
|
|
|
+ self.info("当前option的layout坐标配置异常:%s" % str(curInfo['layout']['bounds']))
|
|
|
+ else:
|
|
|
+ self.info("当前option的layout坐标为:%s" % str(curInfo['layout']['bounds']))
|
|
|
+ retImg = os.path.join(getSATTmpDIR(), "menutree_runpath_layout.png")
|
|
|
+ COptionAction.__imgCMP.saveCropPic(img, retImg, curInfo['layout']['bounds'])
|
|
|
+ return retImg
|
|
|
|
|
|
'''
|
|
|
函数:调用根节点快捷键(中间节点不需要快捷键;);
|
|
@@ -217,6 +234,7 @@ class COptionAction(CBaseLog):
|
|
|
# 获取父节点
|
|
|
parentOption = self.__optionValueInfo['option']
|
|
|
else:
|
|
|
+ getStatus, nextOptionInfo = self.getNextOptionInfo()
|
|
|
if self.__curOptionInfo is None or self.__curOptionInfo.__len__() == 0:
|
|
|
self.error(u"当前option[%s]信息空" % str(self.__curOptionName))
|
|
|
return False, False
|
|
@@ -319,7 +337,7 @@ class COptionAction(CBaseLog):
|
|
|
# 注:value表中的option实际并没有兄弟项,取的是所有value项
|
|
|
if isValueSheet and siblingTextList.__len__():
|
|
|
if siblingTextList[0].startswith('range('):
|
|
|
- self.info(u"识别的内容是value表数字内容(range(0,xx)类型)")
|
|
|
+ self.info(u"识别的内容是value表数字内容(range(x,y)类型)")
|
|
|
isNumberText = True
|
|
|
|
|
|
# 清除之前的value值;
|
|
@@ -330,12 +348,14 @@ class COptionAction(CBaseLog):
|
|
|
ocrThreshold, curOthers['marquee'],
|
|
|
isNumberText, isValueSheet)
|
|
|
else:
|
|
|
- return self.__getStaticPicText(self.takePicture() if staticPic is None else staticPic, curOption,
|
|
|
- optionTextList,
|
|
|
- siblingTextList,
|
|
|
- ocrConfigList,
|
|
|
- ocrThreshold,
|
|
|
- isNumberText, isValueSheet)
|
|
|
+ isFocus, isTarget, text = self.__getStaticPicText(self.takePicture() if staticPic is None else staticPic,
|
|
|
+ curOption,
|
|
|
+ optionTextList,
|
|
|
+ siblingTextList,
|
|
|
+ ocrConfigList,
|
|
|
+ ocrThreshold,
|
|
|
+ isNumberText, isValueSheet)
|
|
|
+ return isTarget, text
|
|
|
# endif
|
|
|
|
|
|
'''
|
|
@@ -426,10 +446,12 @@ class COptionAction(CBaseLog):
|
|
|
|
|
|
def back2ParentNode(self, isReduce=True):
|
|
|
# 获取当前option信息;
|
|
|
+ wait = 1
|
|
|
+ duration = 1
|
|
|
if self.getCurOptionInfo():
|
|
|
- backKey = self.__curOptionInfo['back_key']
|
|
|
+ tKeyDict = self.__curOptionInfo['toparent_key']
|
|
|
else:
|
|
|
- backKey = self.__optionValueInfo['back_key']
|
|
|
+ tKeyDict = self.__optionValueInfo['toparent_key']
|
|
|
# 同时,根据是否有发送enter key和值类型来判断是否需要多发次返回。
|
|
|
if not self.__isEnterKeyInValue:
|
|
|
# 标记为True,防止重复进入.
|
|
@@ -450,13 +472,39 @@ class COptionAction(CBaseLog):
|
|
|
# 如果是进度条数据,没有enter键;
|
|
|
self.back2ParentNode(False)
|
|
|
|
|
|
- if backKey.__len__() == 0:
|
|
|
- self.sendKey('return', 1, 1)
|
|
|
+ # 有可能没有toParent_key参数栏,或者有toParent_key参数栏,但参数栏为空
|
|
|
+ if tKeyDict.__len__() == 0 or tKeyDict['key'].__len__() == 0:
|
|
|
+ self.sendKey('return', duration=duration)
|
|
|
else:
|
|
|
- self.sendKey(backKey, 1, 1)
|
|
|
+ keyList = tKeyDict['key'].split(",")
|
|
|
+ if tKeyDict["duration"] != "":
|
|
|
+ duration = tKeyDict['duration']
|
|
|
+ if tKeyDict["wait"] != "":
|
|
|
+ wait = float(tKeyDict['wait'])
|
|
|
+ self.info(u"toParentKey存在参数,keyList=%s,duration=%s,wait=%s" % (keyList, duration, wait))
|
|
|
+ for key in keyList:
|
|
|
+ self.sendKey(key, duration=duration)
|
|
|
+
|
|
|
+ time.sleep(wait)
|
|
|
# 返回,自减;
|
|
|
if isReduce:
|
|
|
- self.__pos -= 1
|
|
|
+ if tKeyDict.__len__() > 0 and tKeyDict["tolevel"] != "":
|
|
|
+ level = tKeyDict['tolevel'].lower()
|
|
|
+ self.info(u"toParentkey将回退至level:%s" % level)
|
|
|
+ self.__pos = self.__getLevelIndex(level) + 1
|
|
|
+ else:
|
|
|
+ self.__pos -= 1
|
|
|
+ self.getCurOptionInfo()
|
|
|
+
|
|
|
+ '''
|
|
|
+ 在忽略大小写的情况下,获取到该level对应的g_level的下标值
|
|
|
+ '''
|
|
|
+
|
|
|
+ def __getLevelIndex(self, level):
|
|
|
+ s_level = []
|
|
|
+ for lvStr in g_level:
|
|
|
+ s_level.append(lvStr.lower())
|
|
|
+ return s_level.index(level)
|
|
|
|
|
|
'''
|
|
|
函数:进入当前节点,只对路径节点有效,value节点不处理;
|
|
@@ -477,6 +525,8 @@ class COptionAction(CBaseLog):
|
|
|
self.sendKey(optionEnterKey, 1, waitTime)
|
|
|
# 进入下层,自增
|
|
|
self.__pos += 1
|
|
|
+ # 重新获取次信息;
|
|
|
+ self.getCurOptionInfo()
|
|
|
else:
|
|
|
if not self.__isEnterKeyInValue:
|
|
|
self.info(u"节点已在value上,且没有触发过enter key")
|
|
@@ -506,6 +556,8 @@ class COptionAction(CBaseLog):
|
|
|
self.error(u"pos值[%d]超出路径范围:[0-%d]" % (pos, self.__optionPaths.__len__()))
|
|
|
return
|
|
|
self.__pos = pos
|
|
|
+ # 变量层级后,需要重新获取当前节点信息,保证外部调用正常;
|
|
|
+ self.getCurOptionInfo()
|
|
|
|
|
|
'''
|
|
|
函数:设置目标option的值, 只设置数值型value和输入型value(选择型value不需要此步骤).
|
|
@@ -610,6 +662,27 @@ class COptionAction(CBaseLog):
|
|
|
|
|
|
return True
|
|
|
|
|
|
+ '''
|
|
|
+ 函数:返回下一个option的详细信息;
|
|
|
+ 参数:无
|
|
|
+ 返回:Boolean、option info。
|
|
|
+ '''
|
|
|
+
|
|
|
+ def getNextOptionInfo(self):
|
|
|
+ if self.__optionPaths is None or self.__optionPaths.__len__() == 0:
|
|
|
+ self.error(u"paths路径空")
|
|
|
+ return False, None
|
|
|
+
|
|
|
+ if self.__pos + 1 >= self.__optionPaths.__len__():
|
|
|
+ self.warn(u"已到达value节点,无法获取路径信息")
|
|
|
+ return False, None
|
|
|
+
|
|
|
+ nextOptionName = self.__optionPaths[g_level[self.__pos + 1]]['option']
|
|
|
+ return self.__optionExcel.getOptionInfo(nextOptionName, self.__optionPaths)
|
|
|
+
|
|
|
+ def getCurParentInfo(self):
|
|
|
+ pass
|
|
|
+
|
|
|
'''
|
|
|
函数:检测路径是否有效;
|
|
|
参数:无
|
|
@@ -651,17 +724,17 @@ class COptionAction(CBaseLog):
|
|
|
函数:获取静态图片文本内容
|
|
|
参数:(略,请看调用函数)
|
|
|
注意:
|
|
|
- 返回:Boolean、文本识别内容。成功识别出文本,返回True及文本内容。
|
|
|
+ 返回:Boolean、Boolean、文本识别内容。
|
|
|
+ 是否成功聚焦、是否聚焦在目标节点上、聚焦框识别的文本内容。
|
|
|
'''
|
|
|
|
|
|
def __getStaticPicText(self, pic, optionName, optionTextList, siblingTextList, ocrConfigList, ocrThreshold,
|
|
|
- isNumberText,
|
|
|
- isValueSheet, aliveKey=None):
|
|
|
+ isNumberText, isValueSheet, aliveKey=None):
|
|
|
# 获取图片焦点框;
|
|
|
found, focusBox = self.__optionFocus.findFocusByIcon(pic, optionName, isValueSheet)
|
|
|
if found is False:
|
|
|
self.debug(u"未找到[%s]聚集框" % optionName)
|
|
|
- return False, None
|
|
|
+ return False, False, None
|
|
|
|
|
|
# 如果有鲜活键;
|
|
|
self.sendAliveKey(aliveKey)
|
|
@@ -673,7 +746,7 @@ class COptionAction(CBaseLog):
|
|
|
self.__imgCMP.saveCropPic(pic, text_pic, textBox)
|
|
|
if not os.path.exists(text_pic):
|
|
|
self.error(u"%s截取文本图片失败:%s" % (optionName, text_pic))
|
|
|
- return False, None
|
|
|
+ return False, False, None
|
|
|
|
|
|
# 是否在某个兄弟项中;
|
|
|
isOnSibling = False
|
|
@@ -706,7 +779,7 @@ class COptionAction(CBaseLog):
|
|
|
numberText = float(numberTextList[numberTextList.__len__() - 1])
|
|
|
# 记录value值;
|
|
|
self.__optionValueText = numberText
|
|
|
- return True, numberText
|
|
|
+ return True, True, numberText
|
|
|
except Exception:
|
|
|
continue
|
|
|
else:
|
|
@@ -718,12 +791,13 @@ class COptionAction(CBaseLog):
|
|
|
if siblingText in curFocusText or strcmp(siblingText, curFocusText):
|
|
|
isOnSibling = True
|
|
|
self.info(u"当前焦点在[%s], 目标焦点为[%s]" % (siblingText, optionName))
|
|
|
+ self.info(u"optionTextList:%s" % optionTextList)
|
|
|
# 再判断,该兄弟项是否为目标节点(curOption);
|
|
|
for optionText in optionTextList:
|
|
|
optionText = optionText.lower()
|
|
|
# 若当前兄弟项为目标option返回True、文本;
|
|
|
if strcmp(optionText, siblingText):
|
|
|
- return True, curFocusText
|
|
|
+ return True, True, curFocusText
|
|
|
# endif
|
|
|
# endfor
|
|
|
# 在兄弟项中,退出循环;
|
|
@@ -735,12 +809,12 @@ class COptionAction(CBaseLog):
|
|
|
self.error(u"未聚集到任何[%s]的兄弟项中" % optionName)
|
|
|
else:
|
|
|
self.info("未聚集到目标节点[%s],当前文本=%s" % (optionName, curFocusText))
|
|
|
- return False, curFocusText
|
|
|
+ return found, False, curFocusText
|
|
|
# endif
|
|
|
# endfor
|
|
|
|
|
|
# 默认返回;
|
|
|
- return False, 0 if isNumberText else ""
|
|
|
+ return found, False, 0 if isNumberText else ""
|
|
|
|
|
|
'''
|
|
|
函数:获取动态图片文本内容
|
|
@@ -752,20 +826,22 @@ class COptionAction(CBaseLog):
|
|
|
def __getDynamicPicText(self, optionName, optionTextList, siblingTextList, ocrConfigList, ocrThreshold, marqueeDict,
|
|
|
isNumberText, isValueSheet):
|
|
|
# 判断图片是否动态:截图两次,判断两次文本内容是否相同;
|
|
|
- firstRetsult, firstText = self.__getStaticPicText(self.takePicture(), optionName, optionTextList,
|
|
|
- siblingTextList, ocrConfigList,
|
|
|
- ocrThreshold, isNumberText, isValueSheet)
|
|
|
- if firstRetsult is False:
|
|
|
+ firstFocus, firstTarget, firstText = self.__getStaticPicText(self.takePicture(), optionName, optionTextList,
|
|
|
+ siblingTextList,
|
|
|
+ [{"lan": "ChinesePRC+English", "type": 10001}],
|
|
|
+ ocrThreshold, isNumberText, isValueSheet)
|
|
|
+ if firstFocus is False:
|
|
|
self.error(u"[%s]第一次截图未识别出聚焦框" % optionName)
|
|
|
return False, None
|
|
|
|
|
|
# 发送鲜活键, 保证界面鲜活;
|
|
|
self.sendAliveKey(marqueeDict['alive_key'])
|
|
|
# 第二次截图;
|
|
|
- secondRetsult, secondText = self.__getStaticPicText(self.takePicture(), optionName, optionTextList,
|
|
|
- siblingTextList, ocrConfigList,
|
|
|
- ocrThreshold, isNumberText, isValueSheet)
|
|
|
- if secondRetsult is False:
|
|
|
+ secondFocus, secondTarget, secondText = self.__getStaticPicText(self.takePicture(), optionName, optionTextList,
|
|
|
+ siblingTextList,
|
|
|
+ [{"lan": "ChinesePRC+English", "type": 10001}],
|
|
|
+ ocrThreshold, isNumberText, isValueSheet)
|
|
|
+ if secondFocus is False:
|
|
|
self.error(u"[%s]第二次截图未识别出聚焦框" % optionName)
|
|
|
return False, None
|
|
|
|
|
@@ -795,9 +871,11 @@ class COptionAction(CBaseLog):
|
|
|
ocrTextList = []
|
|
|
# 对截图进行文本识别分析;
|
|
|
for pic in picList:
|
|
|
- result, text = self.__getStaticPicText(pic, optionName, optionTextList, siblingTextList, ocrConfigList,
|
|
|
- ocrThreshold, isNumberText, isValueSheet, marqueeDict['alive_key'])
|
|
|
- if result is True:
|
|
|
+ isFocus, isTarget, text = self.__getStaticPicText(pic, optionName, optionTextList, siblingTextList,
|
|
|
+ ocrConfigList,
|
|
|
+ ocrThreshold, isNumberText, isValueSheet,
|
|
|
+ marqueeDict['alive_key'])
|
|
|
+ if isTarget is True:
|
|
|
ocrTextList.append(text)
|
|
|
# 发送鲜活键;
|
|
|
self.sendAliveKey(marqueeDict['alive_key'])
|
|
@@ -941,20 +1019,20 @@ class COptionAction(CBaseLog):
|
|
|
返回:无
|
|
|
'''
|
|
|
|
|
|
- def sendKey(self, key, count=1, wait=1):
|
|
|
+ def sendKey(self, key, count=1, duration=1):
|
|
|
if key is not None and key.__len__() > 0:
|
|
|
if type(key) == list:
|
|
|
for k in key:
|
|
|
# 清除前后空格;
|
|
|
k = k.lstrip()
|
|
|
k = k.rstrip()
|
|
|
- COptionAction.__redRat3.sendKey(k, 1, wait)
|
|
|
+ COptionAction.__redRat3.sendKey(k, 1, duration)
|
|
|
else:
|
|
|
key = str(key)
|
|
|
# 清除前后空格;
|
|
|
key = key.lstrip()
|
|
|
key = key.rstrip()
|
|
|
- COptionAction.__redRat3.sendKey(key, count, wait)
|
|
|
+ COptionAction.__redRat3.sendKey(key, count, duration)
|
|
|
else:
|
|
|
self.error(u"error:按键内容空")
|
|
|
|