Executor.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. #-*- coding:utf-8 -*-
  2. import os, sys, time
  3. import xlrd
  4. import xlwt
  5. import sqlite3
  6. import json
  7. from ssat_sdk.picture.feature_detect import FeatureDetect
  8. from ssat_sdk.utils import LoggingUtil
  9. from ssat_sdk.picture import image_util
  10. class CExcelData():
  11. def __init__(self):
  12. # 编号;
  13. self.num = 0
  14. # 类型;
  15. self.type = ''
  16. # 控件id;
  17. self.ctrlid = ''
  18. # 类型描述;
  19. self.desc = ''
  20. # 类型事件;
  21. self.event = ''
  22. # 类型参数;
  23. self.params = ''
  24. # 类型结果;
  25. self.typeresult = ''
  26. # 事件结果;
  27. self.eventresult = ''
  28. def getdata(self, data):
  29. if data is not None:
  30. self.num, self.type, self.ctrlid, self.desc, self.event, self.params, self.typeresult, self.eventresult = tuple(data)
  31. #end-fun
  32. def tolist(self):
  33. return [self.num, self.type, self.ctrlid, self.desc, self.event, self.params, self.typeresult, self.eventresult]
  34. #end-fun
  35. class CImgView():
  36. def __init__(self):
  37. # 图元id;
  38. self.id = ''
  39. # 图元名称;
  40. self.name = ''
  41. # 图元类型:按钮、滑块
  42. self.type = ''
  43. # 图元领空区域;
  44. self.airspace = []
  45. # 图元未选时图标区域;
  46. self.iconarea = []
  47. # 图元未选时文本区域;
  48. self.textarea = []
  49. # 图元未选时文本内容;
  50. self.textcontent = ''
  51. # 图元未选时图标内容:使用路径;
  52. self.iconcontent = ''
  53. # 图元选中时图标区域;
  54. self.iconarea2 = []
  55. # 图元选中时文本区域;
  56. self.textarea2 = []
  57. # 图元选中时的文件内容;
  58. self.textcontent2 = ''
  59. # 图元选中时的图标内容;
  60. self.iconcontent2 = ''
  61. # 展开键;
  62. self.openkey = ''
  63. # 返回键;
  64. self.returnkey = ''
  65. # 弹出键;
  66. self.popkey = ''
  67. # 图元所属图区id;
  68. self.areaid = 0
  69. # 图元关联图区id;
  70. self.nextareaid = 0
  71. def getdata(self,data):
  72. self.id = data[0]
  73. self.name = data[1]
  74. self.type = data[2]
  75. self.airspace = [] if data[3] is None else json.loads(data[3])
  76. self.iconarea = [] if data[4] is None else json.loads(data[4])
  77. self.textarea = [] if data[5] is None else json.loads(data[5])
  78. self.textcontent = data[6]
  79. self.iconcontent = data[7]
  80. self.iconarea2 = data[8]
  81. self.textarea2 = data[9]
  82. self.textcontent2 = data[10]
  83. self.iconcontent2 = data[11]
  84. self.openkey = data[12]
  85. self.returnkey = data[13]
  86. self.popkey = data[14]
  87. self.areaid = data[15]
  88. self.nextareaid = data[16]
  89. class CImgArea():
  90. def __init__(self):
  91. self.id = ''
  92. self.name = ''
  93. self.isroot = False
  94. self.popkey = ''
  95. self.returnkey = ''
  96. self.examplepic = ''
  97. self.coodinate = []
  98. self.bgproperty = ''
  99. self.uidtype = ''
  100. self.uidcontent = ''
  101. self.uidarea = []
  102. self.layouttype = ''
  103. self.direction = ''
  104. self.method = ''
  105. self.refcoordFocusArea = []
  106. self.refcoordIconArea = []
  107. self.refcoordTextArea = []
  108. self.methodParam = {}
  109. self.layoutParam = {}
  110. self.ocrParam = []
  111. def getdata(self, data):
  112. self.id = data[0]
  113. self.name = data[1]
  114. self.isroot = data[2]
  115. self.popkey = data[3]
  116. self.returnkey = data[4]
  117. self.examplepic = data[5]
  118. self.coodinate = [] if data[6] is None else json.loads(data[6])
  119. self.bgproperty = data[7]
  120. self.uidtype = data[8]
  121. self.uidcontent = data[9]
  122. self.uidarea = data[10]
  123. self.layouttype = data[11]
  124. self.direction = data[12]
  125. self.method = data[13]
  126. self.refcoordFocusArea = [] if data[14] is None else json.loads(data[14])
  127. self.refcoordIconArea = [] if data[15] is None else json.loads(data[15])
  128. self.refcoordTextArea = [] if data[16] is None else json.loads(data[16])
  129. self.methodParam = {} if data[17] is None else json.loads(data[17])
  130. self.layoutParam = {} if data[18] is None else json.loads(data[18])
  131. self.ocrParam = [] if data[19] is None else json.loads(data[19])
  132. #end-fun
  133. class CParameters():
  134. def __init__(self):
  135. self.id = 0
  136. self.areaid = 0
  137. self.method = ''
  138. self.params = ''
  139. def getdata(self,data):
  140. self.id = data[0]
  141. self.areaid = data[1]
  142. self.method = data[2]
  143. self.params = data[3]
  144. if self.method == u'全局二值化':
  145. print(u'全局二值化')
  146. elif self.method == u'局部二值化':
  147. pass
  148. elif self.method == u'方差二值化':
  149. pass
  150. elif self.method == u'模板匹配':
  151. pass
  152. elif self.method == u'形状匹配':
  153. pass
  154. #end-fun
  155. class CExecutor():
  156. def __init__(self, xls_path, db_path):
  157. # db连接对象;
  158. self.conn = None
  159. # 游标;
  160. self.cursor = None
  161. # excel路径;
  162. self.xls_path = xls_path
  163. # db路径;
  164. self.db_path = db_path
  165. # excel数据;
  166. self.xls_data = []
  167. # 识别类对象;
  168. self.feature = FeatureDetect()
  169. #end-fun
  170. def read_excel(self, path = None):
  171. if path is None:
  172. path = self.xls_path
  173. #end-if
  174. # 打开文件;
  175. wb = xlrd.open_workbook(filename=path)
  176. if wb is None:
  177. return
  178. #通过索引获取表格;
  179. sheet1 = wb.sheet_by_index(0)
  180. for i in range(1, sheet1.nrows):
  181. # 获取行内容;
  182. rows = sheet1.row_values(i)
  183. data = CExcelData()
  184. data.getdata(rows)
  185. self.xls_data.append(data)
  186. #end-for
  187. #end-fun
  188. def get_conn(self, path = None):
  189. if path is None:
  190. path = self.db_path
  191. #end-if
  192. if os.path.exists(path) and os.path.isfile(path) :
  193. self.conn = sqlite3.connect(path)
  194. #end-if
  195. #end-fun
  196. def get_cursor(self) :
  197. if self.conn is not None:
  198. self.cursor = self.conn.cursor()
  199. else:
  200. self.cursor = self.get_conn().cursor()
  201. #end-fun
  202. def fetchone(self, sql, data) :
  203. if self.conn is None:
  204. return
  205. if sql is not None and sql != '' :
  206. if data is not None :
  207. #Do this instead
  208. d = (data, )
  209. cu = self.cursor
  210. cu.execute(sql, d)
  211. rec = cu.fetchall()
  212. return rec
  213. else:
  214. print('the [{}] equal None!'.format(data))
  215. return None
  216. else:
  217. print('the [{}] is empty or equal None!'.format(sql))
  218. return None
  219. #end-fun
  220. def getImgViewData(self,id):
  221. sql = "SELECT ImgView.Id,"\
  222. "ImgView.Name,"\
  223. "ImgView.Type,"\
  224. "ImgView.AirspaceArea,"\
  225. "ImgView.IconArea,"\
  226. "ImgView.TextArea,"\
  227. "ImgView.TextContent,"\
  228. "ImgView.IconContent,"\
  229. "ImgView.IconArea2,"\
  230. "ImgView.TextArea2,"\
  231. "ImgView.TextContent2,"\
  232. "ImgView.IconContent2,"\
  233. "ImgView.OpenKey,"\
  234. "ImgView.ReturnKey,"\
  235. "ImgView.PopKey,"\
  236. "ImgView.AreaId,"\
  237. "ImgView.NextAreaId "\
  238. "FROM ImgView WHERE id = ?"
  239. # 获取记录集;
  240. record = self.fetchone(sql, id)
  241. data = CImgView()
  242. if record is not None:
  243. if len(record) > 0:
  244. data.getdata(record[0])
  245. return data
  246. return None
  247. #end-fun
  248. def getImgAreaData(self, id):
  249. sql = "SELECT ImgArea.Id,"\
  250. "ImgArea.Name,"\
  251. "ImgArea.IsRoot,"\
  252. "ImgArea.PopKey,"\
  253. "ImgArea.ReturnKey,"\
  254. "ImgArea.ExamplePicture,"\
  255. "ImgArea.Coordinate,"\
  256. "ImgArea.BackgroundProperties,"\
  257. "ImgArea.UIdType,"\
  258. "ImgArea.UIdContent,"\
  259. "ImgArea.UIdArea,"\
  260. "ImgArea.LayoutType,"\
  261. "ImgArea.Direction,"\
  262. "ImgArea.Method,"\
  263. "ImgArea.refcoordFocusArea,"\
  264. "ImgArea.refcoordIconArea,"\
  265. "ImgArea.refcoordTextArea,"\
  266. "ImgArea.MethodParam,"\
  267. "ImgArea.LayoutParam,"\
  268. "ImgArea.OCRParam "\
  269. "FROM ImgArea WHERE id = ?"
  270. # 获取记录集;
  271. record = self.fetchone(sql, id)
  272. data = CImgArea()
  273. if record is not None:
  274. if len(record) > 0:
  275. data.getdata(record[0])
  276. return data
  277. return None
  278. #end-fun
  279. def getParameters(self, areaid):
  280. sql = "SELECT Parameter.Id,"\
  281. "Parameter.AreaId,"\
  282. "Parameter.Method,"\
  283. "Parameter.Parameters "\
  284. "FROM Parameter WHERE AreaId = ?"
  285. # 获取记录集;
  286. record = self.fetchone(sql, areaid)
  287. data = CParameters()
  288. if record is not None:
  289. if len(record) > 0:
  290. data.getdata(record[0])
  291. return data
  292. return None
  293. #end-fun
  294. # 1、找到加返回True,否则False
  295. # 2、返回当前焦点坐标;
  296. def doVerifyOnTargetCtrl(self, pel_data, map_data):
  297. # 截图,原图路径;
  298. screenshot = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "TVShot_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  299. self.feature.vp.takePicture(screenshot)
  300. # 根据方法分类执行;
  301. if map_data.method == u"全局二值化":
  302. contour = self.feature.getGrayBinaryContour(screenshot,
  303. map_data.coodinate,
  304. map_data.methodParam['gray'],
  305. 255,
  306. map_data.methodParam['inside'],
  307. map_data.methodParam['min-peri'],
  308. map_data.methodParam['max-peri'],
  309. map_data.methodParam['min-area'],
  310. map_data.methodParam['max-area'],)
  311. # 是否找到轮廓;
  312. if contour is None:
  313. return False, [], screenshot
  314. # 获取文本坐标;
  315. textbox = self.feature.getObjAbsoluteBox(contour, map_data.refcoordFocusArea, map_data.refcoordTextArea)
  316. # ocr识别;
  317. ocrImgPath = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "OCR_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  318. image_util.saveCropPic(screenshot, ocrImgPath, textbox)
  319. result, text = self.feature.OCR.findPicStr(pel_data.textcontent, ocrImgPath, map_data.ocrParam[0], map_data.ocrParam[1], map_data.ocrParam[2])
  320. # 返回结果;
  321. return result, contour, screenshot
  322. elif map_data.method == u"局部二值化":
  323. pass
  324. elif map_data.method == u"方差二值化":
  325. pass
  326. elif map_data.method == u"模板匹配":
  327. # 模板匹配函数需要改造;
  328. setting = {'method': 5, 'colorType': 0, 'thresholdVal': 0, 'thresholdMaxVal': 255, 'matchVal': map_data.methodParam['match'] }
  329. match_result = self.feature.matchSingleImage(screenshot, map_data.coodinate, map_data.methodParam['tempdir'], setting)
  330. if match_result is None:
  331. return False, [], screenshot
  332. else:
  333. # 获取文本坐标;
  334. textbox = self.feature.getObjAbsoluteBox(match_result['coordinate'], map_data.refcoordFocusArea, map_data.refcoordTextArea)
  335. # ocr识别;
  336. ocrImgPath = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "OCR_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  337. image_util.saveCropPic(screenshot, ocrImgPath, textbox)
  338. result, text = self.feature.OCR.findPicStr(pel_data.textcontent, ocrImgPath, map_data.ocrParam[0], map_data.ocrParam[1], map_data.ocrParam[2])
  339. # 返回结果;
  340. return result, match_result['coordinate'], screenshot
  341. elif map_data.method == u"形状匹配":
  342. pass
  343. # 不存在的方法,直接返回False;
  344. return False, [], screenshot
  345. #end-fun
  346. # 判断是否在目标图区上;
  347. # 根据唯一标识内容来判断;
  348. def doVerifyOnTargetMapArea(self, map_data):
  349. result, coodr = False, []
  350. # 截图,原图路径;
  351. screenshot = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "TVShot_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  352. self.feature.vp.takePicture(screenshot)
  353. if map_data.uidtype == u"图标":
  354. # 模板匹配函数需要改造;
  355. setting = {'method': 5, 'colorType': 0, 'thresholdVal': 0, 'thresholdMaxVal': 255, 'matchVal': map_data.methodParam['match'] }
  356. match_result = self.feature.matchSingleImage(screenshot, map_data.coodinate, map_data.methodParam['tempdir'], setting)
  357. if match_result is None:
  358. return False, [], screenshot
  359. else:
  360. return True, match_result['coordinate'], screenshot
  361. elif map_data.uidtype == u"文本":
  362. pass
  363. elif map_data.uidtype == u"颜色":
  364. pass
  365. elif map_data.uidtype == u"轮廓":
  366. pass
  367. elif map_data.uidtype == u"形状":
  368. pass
  369. elif map_data.uidtype == u"":
  370. pass
  371. # 返回结果;
  372. return result, coodr, screenshot
  373. # 执行事件;
  374. def doCtrlEvent(self, xls_data, pel_data, map_data):
  375. # 执行前截图分析;
  376. screenshot = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "TVShot_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  377. self.feature.vp.takePicture(screenshot)
  378. # 类型判断;
  379. if pel_data.type == u"滑块":
  380. if xls_data.event == u"编辑":
  381. if map_data.layouttype == u"图独":
  382. # 获取文本坐标;
  383. textbox = self.feature.getObjAbsoluteBox(map_data.coodinate, map_data.refcoordFocusArea, map_data.refcoordTextArea)
  384. # ocr识别;
  385. ocrImgPath = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "OCR_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  386. image_util.saveCropPic(screenshot, ocrImgPath, textbox)
  387. text = self.feature.OCR.getStrWithImgProcess(ocrImgPath, map_data.ocrParam[2], map_data.ocrParam[0], map_data.ocrParam[1])
  388. if text is not None and text is not '':
  389. count = int(xls_data.params) - int(text)
  390. if count > 0:
  391. self.feature.redRat3.sendKey('right', count, 0.1)
  392. elif count < 0:
  393. self.feature.redRat3.sendKey('left', abs(count), 0.1)
  394. # 执行后截图分析;
  395. screenshot = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "TVShot_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  396. self.feature.vp.takePicture(screenshot)
  397. # 验证结果是否正确;# ocr识别;
  398. ocrImgPath = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "OCR_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  399. image_util.saveCropPic(screenshot, ocrImgPath, textbox)
  400. text = self.feature.OCR.getStrWithImgProcess(ocrImgPath, map_data.ocrParam[2], map_data.ocrParam[0], map_data.ocrParam[1])
  401. if text is not None and text is not '':
  402. if int(xls_data.params) == int(text):
  403. return True, textbox, screenshot
  404. return False, textbox, screenshot
  405. else:
  406. print('ocr convert error!')
  407. return False, textbox, screenshot
  408. #end-if
  409. elif xls_data.event == u"单击":
  410. self.feature.redRat3.sendKey(pel_data.openkey)
  411. # 是否成功进入关联图区;
  412. elif xls_data.event == u"返回":
  413. self.feature.redRat3.sendKey(pel_data.returnkey)
  414. # 是否成功返回上层图区;
  415. elif xls_data.event == u"弹出":
  416. self.feature.redRat3.sendKey(pel_data.popkey)
  417. # 是否成功弹出某图区;
  418. #end-if
  419. elif pel_data.type == u"按钮":
  420. if xls_data.event == u"单击":
  421. self.feature.redRat3.sendKey(pel_data.openkey)
  422. # 是否成功进入关联图区;
  423. elif xls_data.event == u"返回":
  424. self.feature.redRat3.sendKey(pel_data.returnkey)
  425. # 是否成功返回上层图区;
  426. elif xls_data.event == u"弹出":
  427. self.feature.redRat3.sendKey(pel_data.popkey)
  428. # 是否成功弹出某图区;
  429. elif pel_data.type == u"编辑框":
  430. pass
  431. # 默认返回True;
  432. return True, [], screenshot
  433. #end-fun
  434. # 根据布局方式,到达目标控件;
  435. def doMove2TargetCtrl(self, pel_data, map_data):
  436. print pel_data.id, pel_data.name, pel_data.areaid, map_data.id, map_data.name
  437. key, result, curbox, lastbox, screenshot = '', False, [], [], ''
  438. if map_data.layouttype == u"网格":
  439. pass
  440. elif map_data.layouttype == u"纵向列表":
  441. # 开始位置;用于循环列表;
  442. beginbox = []
  443. # 默认遍历方向;
  444. key = 'down'
  445. # 遍历计数;
  446. count = 0
  447. # 是否逆序遍历;
  448. isAdverse = False
  449. while True:
  450. result, curbox, screenshot = self.doVerifyOnTargetCtrl(pel_data, map_data)
  451. # 找到目标焦点;
  452. if result is True:
  453. break
  454. # 正序遍历;
  455. if isAdverse is False:
  456. # 当前焦点框与上次焦点框相同,认为到达边界端;
  457. if curbox == lastbox:
  458. key = 'up'#改变寻路方向;
  459. # 标记已开始逆序
  460. isAdverse = True
  461. # 根据count计数,直接返回原本位置;
  462. self.feature.redRat3.sendKey(key,count,0.2)
  463. # 循环列表完成一次遍历回到beginbox;
  464. if curbox == beginbox:
  465. break
  466. else:
  467. # 已逆序,且再次到达另一边界端;
  468. if curbox == lastbox:
  469. break
  470. # 记录起始位置;
  471. if beginbox == []:
  472. beginbox = curbox
  473. # 记录本次位置;
  474. lastbox = curbox
  475. # 下一位置;
  476. self.feature.redRat3.sendKey(key)
  477. #end-while
  478. elif map_data.layouttype == u"横向列表":
  479. # 开始位置;用于循环列表;
  480. beginbox = []
  481. # 默认遍历方向;
  482. key = 'right'
  483. # 遍历计数;
  484. count = 0
  485. # 是否逆序遍历;
  486. isAdverse = False
  487. while True:
  488. result, curbox, screenshot = self.doVerifyOnTargetCtrl(pel_data, map_data)
  489. # 找到目标焦点;
  490. if result is True:
  491. break
  492. # 正序遍历;
  493. if isAdverse is False:
  494. # 当前焦点框与上次焦点框相同,认为到达边界端;
  495. if curbox == lastbox:
  496. key = 'left' # 改变寻路方向;
  497. # 标记已开始逆序
  498. isAdverse = True
  499. # 根据count计数,直接返回原本位置;
  500. self.feature.redRat3.sendKey(key, count, 0.2)
  501. # 循环列表完成一次遍历回到beginbox;
  502. if curbox == beginbox:
  503. break
  504. else:
  505. # 已逆序,且再次到达另一边界端;
  506. if curbox == lastbox:
  507. break
  508. # 记录起始位置;
  509. if beginbox == []:
  510. beginbox = curbox
  511. # 记录本次位置;
  512. lastbox = curbox
  513. # 下一位置;
  514. self.feature.redRat3.sendKey(key)
  515. # end-while
  516. elif map_data.layouttype == u"标签列表":
  517. pass
  518. elif map_data.layouttype == u"图独":
  519. return True, [], screenshot
  520. # 返回结果以及坐标;
  521. return result, curbox, screenshot
  522. #end-fun
  523. # 结果比较;
  524. def doResultComparison(self, row, xls_data):
  525. result, desc = True, ''
  526. # 解析json为字典;
  527. try:
  528. data = json.loads(row.params)
  529. except Exception, e:
  530. data = {}
  531. desc = str(e)
  532. if data is None or data == {}:
  533. return False, u'Json参数解析出错=%s'%('数据有误' if desc == '' else desc)
  534. # 根据描述选择方法;
  535. if row.event == u"示例":
  536. # [{"num":13},{"num":8}]
  537. param1 = data[0]
  538. param2 = data[1]
  539. # 解析对应的参数;
  540. for r in xls_data:
  541. if r.num == param1['num']:
  542. param1["data"] = r.eventresult
  543. if r.num == param2['num']:
  544. param2['data'] = r.eventresult
  545. #end-for
  546. print param1,param2
  547. elif row.event == u"明暗对比":
  548. pass
  549. elif row.event == u"":
  550. pass
  551. elif row.event == u"":
  552. pass
  553. elif row.event == u"":
  554. pass
  555. elif row.event == u"":
  556. pass
  557. elif row.event == u"":
  558. pass
  559. elif row.event == u"":
  560. pass
  561. elif row.event == u"":
  562. pass
  563. # 默认返回值;
  564. return result, desc
  565. #end-fun
  566. # 保存结果;
  567. def doSaveResult(self, xls_data, save_path):
  568. # 创建工作簿;
  569. book = xlwt.Workbook()
  570. # 创建sheet;
  571. sheet = book.add_sheet(u'result', cell_overwrite_ok=True)
  572. # 创建标题行;
  573. row0 = [u'编号',u'类型', u'控件ID',u'描述',u'事件',u'事件参数',u'类型结果',u'事件结果']
  574. for i in range(len(row0)):
  575. sheet.write(0, i, row0[i], style = xlwt.XFStyle())
  576. index = 1
  577. # 写入其他数据;
  578. for row in xls_data:
  579. l = row.tolist()
  580. for j in range(len(l)):
  581. sheet.write(index, j, l[j], style = xlwt.XFStyle())
  582. index += 1
  583. #end-for
  584. # 保存xls;
  585. book.save(save_path)
  586. #end-fun
  587. def run(self):
  588. # 读取xls
  589. self.read_excel()
  590. # 打开数据库;
  591. self.get_conn()
  592. # 获取游标;
  593. self.get_cursor()
  594. # 遍历excel数据;
  595. for row in self.xls_data:
  596. if row.type == u'控件操作':
  597. # 获取图元信息;
  598. pel_data = self.getImgViewData(row.ctrlid)
  599. if pel_data is not None:
  600. # 获取图元图区信息;
  601. map_data = self.getImgAreaData(pel_data.areaid)
  602. print pel_data, map_data, row
  603. if map_data is not None:
  604. # 执行弹出按键;
  605. # 注:如果多个控件连续且都在同一个根图区时,多次执行会出问题,需完善这里的判断机制;
  606. if map_data.isroot == 1:
  607. if self.doVerifyOnTargetMapArea(map_data)[0] is False:
  608. self.feature.redRat3.sendKey(map_data.popkey)
  609. self.feature.redRat3.sendKey('down')
  610. # 到达目标图元;
  611. result, coodr, screenshot = self.doMove2TargetCtrl(pel_data, map_data)
  612. # 结果;
  613. row.typeresult = u'{"结果":%s, "坐标":%s, "图像":%s}'%('True' if result is True else 'False', str(coodr), screenshot)
  614. if result is True:
  615. # 执行图元事件;
  616. result, coodr, screenshot = self.doCtrlEvent(row, pel_data, map_data)
  617. row.eventresult = u'{"结果":%s, "坐标":%s, "图像":%s}'%('True' if result is True else 'False', str(coodr), screenshot)
  618. else:
  619. print("unable find target ctrl")
  620. break
  621. else:
  622. print('map data is none')
  623. break
  624. else:
  625. print('pel data is none')
  626. break
  627. #end-if
  628. elif row.type == u'结果比较':
  629. result, desc = self.doResultComparison(row, self.xls_data)
  630. row.eventresult = u'{"结果":%s, "描述":%s}'%('True' if result is True else 'False', desc)
  631. elif row.type == u"截屏":
  632. # 默认截屏一张;
  633. screenshot = os.path.join(LoggingUtil.getCaseRunLogDirPath(), "TVShot_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png")
  634. self.feature.vp.takePicture(screenshot)
  635. row.typeresult = screenshot
  636. #end-for
  637. # 保存结果;
  638. self.doSaveResult(self.xls_data, r'D:\result.xls')
  639. #end-fun
  640. if __name__ == "__main__":
  641. executor = CExecutor(r'F:\scbc-sat\command.xlsx', r'F:\scbc-sat\ui.db')
  642. executor.run()