class AudioStep(adb_step): '''helper class for all audio test steps Refere wifi step and wifi_steps for more details ''' def __init__(self, **kwargs): adb_step.__init__(self, **kwargs) # replacing old uidevice available in testlib/external with standard # uiautomator device class self.uidevice = Device(serial=self.serial) def get_driver_logs(self, file_name): try: self.adb_connection.run_cmd( "echo 'see dmesg' > /sdcard/locallogfile") self.adb_connection.get_file("/sdcard/locallogfile", file_name) except: pass def get_failed_dmsg(self, file_name): try: self.adb_connection.run_cmd("dmesg > /sdcard/localdmsgfile") self.adb_connection.get_file("/sdcard/localdmsgfile", file_name) except: pass def get_ui_dump(self, file_name): # save UI dump try: self.uidevice.dump(out_file=file_name, compressed=False, serial=self.serial) except: pass
def screenshot(dir_data, activity, first_page, dev=None, pkg=''): """ Take the screenshot of the given activity. :param dir_data: :param activity: :param first_page: :param dev: :param pkg: :return: """ logger.info('Try to dump layout XML of ' + activity) if dev is None: dev = Device(UIExerciser.series) dev.screen.on() if activity == '': activity = 'first_page' activity = str(activity).replace('\"', '') # dev.wait.idle() logger.info('Dumping...' + activity) if first_page: UIExerciser.pass_first_page(dev) xml_data = None try: xml_data = dev.dump() except Exception as e: logger.error(e) # The dev may be died, force exit. exit(1) UIExerciser.is_crashed(dev, xml_data) while UIExerciser.is_sms_alarm(dev, xml_data): xml_data = dev.dump() xml_data = ViewClientHandler.fill_ids(xml_data, pkg) logger.info(xml_data) f = open( dir_data + activity + '.xml', "wb", ) f.write(xml_data.encode('utf-8')) f.close() try: logger.info(dev.screenshot(dir_data + activity + '.png')) except Exception as e: logger.error(e) UIExerciser.run_adb_cmd( 'shell /system/bin/screencap -p /sdcard/screenshot.png') UIExerciser.run_adb_cmd('pull /sdcard/screenshot.png ' + dir_data + activity + '.png') return True
def screenshot(self, dir_data, activity, first_page, pkg=''): # current_time = time.strftime(ISOTIMEFORMAT, time.localtime()) self.logger.info('Try to dump layout XML of ' + activity) dev = Device(self.series) dev.screen.on() if activity == '': activity = 'first_page' activity = str(activity).replace('\"', '') # dev.wait.idle() self.logger.info('Dumping...' + activity) if first_page: UIExerciser.pass_first_page(dev) try: xml_data = dev.dump() except Exception as e: print e exit(1) self.is_crashed(dev, xml_data) while self.is_SMS_alarm(dev, xml_data): xml_data = dev.dump() xml_data = ViewClientHandler.fill_ids(xml_data, pkg) self.logger.info(xml_data) f = open( dir_data + activity + '.xml', "wb", ) f.write(xml_data.encode('utf-8')) f.close() try: self.logger.info(dev.screenshot(dir_data + activity + '.png')) except Exception as e: self.logger.error(e) UIExerciser.run_adb_cmd( 'shell /system/bin/screencap -p /sdcard/screenshot.png') UIExerciser.run_adb_cmd('pull /sdcard/screenshot.png ' + dir_data + activity + '.png') return True
class AdbDevice(object): hiddenService = 'com.fuhu.settingshelper/.SettingsHelperService' LIST_SYSTEM = 'system' LIST_ALL = 'all' LIST_3RD_PARTY = '3rd' LIST_RECENT = 'recent' orientation = ['natural', 'left', 'upsidedown', 'right'] def __init__(self, serialno=None): self.lock = threading.Semaphore() self.cmd = AdbCmd(serialno) self.serialno = serialno def connect(self): self.d = Device(self.serialno) self.d.orientation # notify to connect # self.d, self.serialno = ViewClient.connectToDeviceOrExit(serialno=self.serialno) # self.vc = ViewClient(self.d, self.serialno, compresseddump=False, ignoreuiautomatorkilled=True, autodump=False) def startActivity(self, component): component = component.replace('$', '\$') self.cmd.shell(['am', 'start', '-n', component, '--activity-clear-task']) def isConnected(self): if self.__getDevices(self.serialno): return True else: return False def listPackages(self): return self.cmd.shell(['pm', 'list', 'package'], output=True) def reboot(self): self.cmd.reboot() def dump(self, compressed=False): return self.d.dump(compressed=compressed).encode('utf-8') @staticmethod def retrieveSelector(point, selectors): shortestDistance = 500000 result = None for selector in selectors: print selector.className bounds = selector.info['bounds'] if bounds['right'] >= point[0] >= bounds['left'] and bounds['top'] >= point[1] >= bounds['bottom']: return selector for selector in selectors: bounds = selector.info['bounds'] distance = (((bounds['left'] + bounds['top']) / 2 - point[0]) ** 2 + ( (bounds['left'] + bounds['bottom']) / 2 - point[1]) ** 2) ** 0.5 if shortestDistance > distance: shortestDistance = distance result = selector return result def checkSamePoint(self, point, info, isLongClick=False): if not self.isScreenOn(): self.powerBtn() if self.isLocked(): self.unlock() if len(info) == 2: if self.d.info['currentPackageName'] == info['packageName']: self.cmd.shell(['input', 'tap', str(point[0]), str(point[1])]) return {'answer': True, 'reason': 'it is the navigation bar'} else: return {'answer': False, 'reason': 'unknown view'} if info['content-desc'] != '': uiObject = self.d(description=info['content-desc']) if self.__checkIncludePoint(uiObject, point): self.cmd.shell(['input', 'tap', str(point[0]), str(point[1])]) else: uiObject.click() return {'answer': True, 'reason': 'find by description'} if info['text'] != '': uiObject = self.d(text=info['text']) if self.__checkIncludePoint(uiObject, point): self.cmd.shell(['input', 'tap', str(point[0]), str(point[1])]) else: uiObject.click() return {'answer': True, 'reason': 'find by text'} currentViewMap = self.getTouchViewInfo(point) if currentViewMap: if currentViewMap['package'] == info['package']: if currentViewMap['class'] == info['class']: self.d.click(point[0], point[1]) return {'answer': True, 'reason': 'Find the similar view'} else: return {'answer': False, 'reason': 'the view doesn\'t be found.'} else: return {'answer': False, 'reason': 'In the wrong page'} else: return {'answer': False, 'reason': 'the view can\'t be found.'} @staticmethod def __checkIncludePoint(uiObject, point): bounds = uiObject.info['visibleBounds'] result, _ = AdbDevice._parseRange(point, (int(bounds['top']), int(bounds['left'])), (int(bounds['right']), int(bounds['bottom']))) return result @staticmethod def removeKey(d, keys): r = dict(d) for k in keys: if r.has_key(k): del r[k] return r def __getDevices(self, serial): outputRE = re.compile(serial) devices = outputRE.findall(AdbCmd.devices()) if len(devices) > 0: return devices[0] def getTouchViewInfo(self, point, compressed=False): smallestArea = sys.maxint result = None root = ET.fromstring(self.dump(compressed=compressed)) for node in root.iter('node'): print node.get('bounds') bounds = re.match('\[(?P<x1>[\d]+),(?P<y1>[\d]+)\]\[(?P<x2>[\d]+),(?P<y2>[\d]+)\]', node.get('bounds')) if bounds: isInclude, area = AdbDevice._parseRange(point, (int(bounds.group('x1')), int(bounds.group('y1'))), (int(bounds.group('x2')), int(bounds.group('y2')))) if isInclude: if area <= smallestArea: smallestArea = area result = node if result is not None: return result.attrib elif point[1] > self.d.info['displayHeight']: p = {'packageName': self.d.info['currentPackageName'], 'type': 'Navigation Bar'} return p @staticmethod def getBoundsCenter(bounds): bounds = re.match('\[(?P<x1>[\d]+),(?P<y1>[\d]+)\]\[(?P<x2>[\d]+),(?P<y2>[\d]+)\]', bounds) x = (int(bounds.group('x2')) + int(bounds.group('x1'))) / 2 y = (int(bounds.group('y2')) + int(bounds.group('y1'))) / 2 return x, y @staticmethod def _parseRange(point, point1, point2): if point1[0] <= point[0] <= point2[0] and point1[1] <= point[1] <= point2[1]: area = (point2[0] - point1[0]) * (point2[1] - point1[1]) return True, area else: return False, None def viewFilter(self, view): if view.getClass() == self.viewClass: return True else: return False def screenOn(self, status): if status == True: self.d.screen.on() else: self.d.screen.off() def clearLog(self): self.cmd.shell(['logcat', '-c']) def longClick(self, x, y, duration): if y <= self.d.info['displayHeight']: self.d.swipe(x, y, x, y, steps=duration / 10) else: self.cmd.shell(['input', 'tap', str(x), str(y)]) def click(self, x, y): if y <= self.d.info['displayHeight']: self.d.click(x, y) else: self.cmd.shell(['input', 'tap', str(x), str(y)]) def drag(self, x, y, duration): self.d.drag(x[0], x[1], y[0], y[1], steps=duration / 10) def swipe(self, x, y, duration): self.cmd.shell(['input', 'swipe', str(x[0]), str(x[1]), str(y[0]), str(y[1]), str(duration)]) def type(self, text): translate = re.sub(r'([#\(\)\&\*\'\\\"\~\`\|\<\>?\;])', r'\\\1', text) self.cmd.shell(['input', 'text', translate]) # self.d(className="android.widget.EditText").set_text(text) def hideKeyboard(self): if self.isKeyboardShown(): self.backBtn() def unlock(self): if self.isLocked(): self.menuBtn() def isLocked(self): lockScreenRE = re.compile('mShowingLockscreen=(true|false)') m = lockScreenRE.search(self.cmd.dumpsys(['window', 'policy'])) if m is not None: return m.group(1) == 'true' def isScreenOn(self): screenOnRE = re.compile('mScreenOnFully=(true|false)') m = screenOnRE.search(self.cmd.dumpsys(['window', 'policy'])) if m is not None: return m.group(1) == 'true' def powerBtn(self): self.cmd.inputKeyevnt('POWER') def backBtn(self): self.cmd.inputKeyevnt('BACK') def homeBtn(self): self.cmd.inputKeyevnt('HOME') def menuBtn(self): self.cmd.inputKeyevnt('MENU') # def rotate(self, orient): # if orient == 'auto': # self.d.freeze_rotation(False) # elif orient == '0': # self.d.orientation = 'n' # elif orient == '90': # self.d.orientation = 'l' # elif orient == '180': # self.d.freeze_rotation(True) # self._setScreenOrient(2) # elif orient == '270': # self.d.orientation = 'r' def rotate(self, orient): self.d.freeze_rotation(True) index = self.orientation.index(self.d.orientation) if orient == 'left': index -= 1 if index < 0: self._setScreenOrient(len(self.orientation) - 1) else: self._setScreenOrient(index) elif orient == 'right': index += 1 if index >= len(self.orientation): self._setScreenOrient(0) else: self._setScreenOrient(index) def volumeUp(self): self.cmd.inputKeyevnt('VOLUME_UP') def volumeDown(self): self.cmd.inputKeyevnt('VOLUME_DOWN') # def _setAutoRotate(self, status): # if status: # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:1']) # time.sleep(1) # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:1']) # # else: # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:0']) # time.sleep(1) # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:0']) def _setScreenOrient(self, orient): self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:user_rotation', '--bind', 'value:i:' + str(orient)]) def resetPackage(self, package): self.cmd.shell(['pm', 'clear', package]) def takeSnapshot(self, path): ''' screen capture in png format :param path: saved file path :return: None ''' p1 = self.cmd.popen(['screencap', '-p'], stdout=PIPE) p = Popen(['perl', '-pe', 's/\x0D\x0D\x0A/\x0A/g'], stdin=p1.stdout, stdout=PIPE) out, error = p.communicate() ba = QByteArray.fromRawData(out) img = QImage.fromData(ba, 'PNG') orient = self.getCurrDisplay()['orientation'] if orient == 1: img = img.transformed(QMatrix().rotate(-90)) elif orient == 2: img = img.transformed(QMatrix().rotate(-180)) elif orient == 3: img = img.transformed(QMatrix().rotate(-270)) img.save(path, 'PNG') def getCurrDisplay(self): output = self.cmd.dumpsys(['display']) match = re.search('mCurrentOrientation=(?P<orientation>[\d])[\w\d\s\(\),-=]+' + 'mCurrentDisplayRect=Rect\(0, 0 - (?P<width>[\d]+),\s+(?P<height>[\d]+)', output) if match: width = int(match.group('width')) height = int(match.group('height')) orientation = int(match.group('orientation')) mode = 'landscape' if width > height else 'portrait' return {'width': width, 'height': height, 'orientation': orientation, 'mode': mode} def getRealDisplay(self): output = self.cmd.dumpsys(['display']) match = re.search('real\s(?P<width>[\d]+)\sx\s(?P<height>[\d]+)', output) return {'width': int(match.group('width')), 'height': int(match.group('height'))} def getProp(self, propType=None): if propType: return self.cmd.getProp(propType) else: return self.cmd.getProp(propType) def uninstall(self, package): self.cmd.uninstall(package) def install(self, name): self.cmd.install(name) def close(self): pass def checkConnected(self): return self.d.checkConnected() def extractComponentName(self, packageName): if packageName == 'com.google.android.youtube': return 'com.google.android.youtube/.app.honeycomb.Shell$HomeActivity' output = self.cmd.dumpsys(['package', packageName]) try: if os.name == 'nt': splitOutput = output.split('\r\r\n') else: splitOutput = output.split('\r\n') num = splitOutput.index(next(x for x in splitOutput if x.find('android.intent.action.MAIN:') != -1)) if num != -1: print splitOutput[num + 1] return splitOutput[num + 1].split()[1] else: return None except: return None def screenTimeout(self): timeout = self.cmd.getSettings(['system', 'screen_off_timeout']) return long(timeout) / 1000 def setScreenTimeout(self, value): self.cmd.putSettings(['system', 'screen_off_timeout', value]) def isNfcOn(self): match = re.search('mState=(on|off)', self.cmd.dumpsys(['nfc'])) if match: if match.group(1) == 'on': return True else: return False else: return False def isAirPlaneModeOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'airplane_mode_on'])) if match: if match.group(1) == '1': return True else: return False def isInstallUnknownSources(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'install_non_market_apps'])) if match: if match.group(1) == '1': return True else: return False def isKeyboardShown(self): output = self.cmd.dumpsys(['input_method']) result = re.search('mInputShown=(true|false)', output) if result.group(1) == 'true': return True else: return False def isWifiOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'wifi_on'])) if match: if match.group(1) == '1': return True else: return False def isBtOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'bluetooth_on'])) if match: if match.group(1) == '1': return True else: return False def isNoKeepActivityOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'always_finish_activities'])) if match: if match.group(1) == '1': return True else: return False def isDataRoamingOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'data_roaming'])) if match: if match.group(1) == '1': return True else: return False def isAutoRotateOn(self): match = re.search('(0|1)', self.cmd.getSettings(['system', 'accelerometer_rotation'])) if match: if match.group(1) == '1': return True else: return False def isGpsOn(self): state = self.cmd.getSettings(['secure', 'location_providers_allowed']) if state == 'none': return False else: return True def isAutoBrightnessOn(self): match = re.search('(0|1)', self.cmd.getSettings(['system', 'screen_brightness_mode'])) if match: if match.group(1) == '1': return True else: return False def isVibrateWhenRingOn(self): match = re.search('(0|1)', self.cmd.getSettings(['system', 'vibrate_when_ringing'])) if match: if match.group(1) == '1': return True else: return False else: return False def isWindowAniOn(self): match = re.search('(0.0|1.0)', self.cmd.getSettings(['global', 'window_animation_scale'])) if match: if match.group(1) == '0.0': return True else: return False else: return False def isTransitionAnuOn(self): match = re.search('(0.0|1.0)', self.cmd.getSettings(['global', 'transition_animation_scale'])) if match: if match.group(1) == '0.0': return True else: return False else: return False def isDurationAniOn(self): match = re.search('(0.0|1.0)', self.cmd.getSettings(['global', 'animator_duration_scale'])) if match: if match.group(1) == '0.0': return True else: return False else: return False def enableWifi(self, state): if state: self.cmd.shell(['am', 'startservice', '--ez', 'wifi', 'true', '-n', self.hiddenService]) else: self.cmd.shell(['am', 'startservice', '--ez', 'wifi', 'false', '-n', self.hiddenService]) def enableBluetooth(self, state): if state: self.cmd.shell(['am', 'startservice', '--ez', 'bt', 'true', '-n', self.hiddenService]) else: self.cmd.shell(['am', 'startservice', '--ez', 'bt', 'false', '-n', self.hiddenService]) def enableInstallUnknownSources(self, state): if state: self.cmd.putSettings(['global', 'install_non_market_apps', '1']) else: self.cmd.putSettings(['global', 'install_non_market_apps', '0']) def enableNfc(self, state): if state: self.cmd.shell(['service', 'call', 'nfc', '6']) else: self.cmd.shell(['service', 'call', 'nfc', '5']) def enableNoKeepActivity(self, state): if state: self.cmd.putSettings(['global', 'always_finish_activities', '1']) else: self.cmd.putSettings(['global', 'always_finish_activities', '0']) def enableDataRoaming(self, state): if state: self.cmd.putSettings(['global', 'data_roaming', '1']) else: self.cmd.putSettings(['global', 'data_roaming', '0']) def enableAutoRotate(self, state): if state: self.cmd.putSettings(['system', 'accelerometer_rotation', '1']) else: self.cmd.putSettings(['system', 'accelerometer_rotation', '0']) def enableGps(self, state): if state: self.cmd.putSettings(['secure', 'location_providers_allowed', 'gps,network']) else: self.cmd.putSettings(['secure', 'location_providers_allowed', 'none']) def enableAutoBrightness(self, state): if state: self.cmd.putSettings(['system', 'screen_brightness_mode', '1']) else: self.cmd.putSettings(['system', 'screen_brightness_mode', '0']) def enableVibrateRinging(self, state): if state: self.cmd.putSettings(['system', 'vibrate_when_ringing', '1']) else: self.cmd.putSettings(['system', 'vibrate_when_ringing', '0']) def enableVibrateWhenRing(self, state): if state: self.cmd.putSettings(['system', 'vibrate_when_ringing', '1']) else: self.cmd.putSettings(['system', 'vibrate_when_ringing', '0']) def enableWindowAnimator(self, state): if state: self.cmd.putSettings(['global', 'window_animation_scale', '1.0']) else: self.cmd.putSettings(['global', 'window_animation_scale', '0.0']) def enableTransitionAnimator(self, state): if state: self.cmd.putSettings(['global', 'transition_animation_scale', '1.0']) else: self.cmd.putSettings(['global', 'transition_animation_scale', '0.0']) def enableDurationAnimation(self, state): if state: self.cmd.putSettings(['global', 'animator_duration_scale', '1.0']) else: self.cmd.putSettings(['global', 'animator_duration_scale', '0.0']) def enableAirplaneMode(self, state): if state: self.cmd.putSettings(['global', 'airplane_mode_on', '1']) self.cmd.shell(['am', 'broadcast', '-a', 'android.intent.action.AIRPLANE_MODE', '--ez', 'state', 'true']) else: self.cmd.putSettings(['global', 'airplane_mode_on', '0']) self.cmd.shell(['am', 'broadcast', '-a', 'android.intent.action.AIRPLANE_MODE', '--ez', 'state', 'false']) def requestPackage(self, t): result = None if t == self.LIST_ALL: result = self.cmd.shell(['pm', 'list', 'packages'], output=True) elif t == self.LIST_SYSTEM: result = self.cmd.shell(['pm', 'list', 'packages', '-s'], output=True) elif t == self.LIST_3RD_PARTY: result = self.cmd.shell(['pm', 'list', 'packages', '-3'], output=True) if result: packages = result.split('\r\n') packages.remove('') packages.sort() return packages def getSerialNumber(self): return self.serialno
class phoneTask: def __init__(self, serial): self.serial = serial self.d = None self.z = None self.taskid = None self.task = None def runStep(self, d, step): self.z.toast("步骤:%s , 任务:%s" % (step["name"], self.task["name"])) pluginName = step["mid"] plugin = __import__("plugins." + pluginName, fromlist=[pluginName]) clazz = plugin.getPluginClass() o = clazz() if step.has_key("arg"): o.action(d, self.z, json.loads(step["arg"])) def handler(self, signum, frame): key = 'timeout_%s' % self.serial activeTime = cache.get(key) if (activeTime is None): self.z.heartbeat() return checkTime = (datetime.datetime.now() - datetime.datetime(2017, 1, 1)).seconds #print checkTime - int(activeTime) if (checkTime - int(activeTime)) > 120: raise AssertionError elif (checkTime - int(activeTime)) > 60: self.z.toast("模块暂停时间过长,即将强制跳过。。。") signal.signal(signal.SIGALRM, self.handler) signal.alarm(60) def deviceTask(self, deviceid, port, zport): self.taskid = dbapi.GetDeviceTask(deviceid) from uiautomator import Device from zservice import ZDevice if self.taskid: self.task = dbapi.GetTask(self.taskid) if (self.task and self.task.get("status") and self.task["status"] == "running"): self.z = ZDevice(deviceid, zport) self.d = Device(deviceid, port) try: self.d.dump(compressed=False) except Exception: logger.error(traceback.format_exc()) while True: steps = dbapi.GetTaskSteps(self.taskid) # 设置zime输入法 self.d.server.adb.cmd( "shell", "ime set com.zunyun.zime/.ZImeService").communicate() self.d.server.adb.cmd( "shell", "am broadcast -a com.zunyun.zime.unlock").communicate( ) for step in steps: try: self.z.heartbeat() signal.signal(signal.SIGALRM, self.handler) signal.alarm(60) self.runStep(self.d, step) signal.alarm(0) except AssertionError: print "ERROR::::%s Moudle execute timeout for 120 seconds" % step[ "name"] except Exception: logger.error(step) logger.error(traceback.format_exc()) time.sleep(3) # 检查设备对应的任务状态 new_taskid = dbapi.GetDeviceTask(deviceid) if new_taskid is None or new_taskid == "": # 任务中删除了该设备 os._exit(0) if (new_taskid != self.taskid): # 设备对应的taskid发生了变化 os._exit(0) task = dbapi.GetTask(new_taskid) if task.get("status") != "running": # 任务状态已停止 os._exit(0) else: os._exit(0) else: os._exit(0) def deviceThread(self, deviceid, port, zport): while True: try: self.deviceTask(deviceid, port, zport) except Exception: logger.error(traceback.format_exc()) time.sleep(5) print("%s thread finished" % deviceid)
Fill the missing ids caused by uiautomator with low API level (<18) :param xml_data: :param package: :return: """ dom = parseString(xml_data.encode("utf-8")) nodes = dom.getElementsByTagName('node') for node in nodes: if node.hasAttribute('resource-id'): return xml_data else: break bounds2ids = ViewClientHandler.dump_view_server(package) if bounds2ids is None: logger.error('Cannot identify the package!') return xml_data logger.info(str(bounds2ids)) for node in nodes: if node.getAttribute('bounds') in bounds2ids: node.setAttribute('resource-id', bounds2ids[node.getAttribute('bounds')]) else: logger.warn('Cannot find ' + node.getAttribute('bounds')) return dom.toxml() if __name__ == '__main__': dev = Device() logger.info(ViewClientHandler.fill_ids(dev.dump(), 'com.kuaihuoyun.driver'))
#! /usr/bin/env python # -*- coding: utf-8 -*- from uiautomator import Device import os if __name__ == '__main__': filename = "dump.xml" d = Device() if os.path.exists(filename): os.remove(filename) d.dump(filename)
#!/usr/bin/python from uiautomator import Device import sys # get the target device d = Device(sys.argv[1]) # dump ui xml d.dump(sys.argv[2], False)
return ChromeSwitcher if __name__ == "__main__": import sys reload(sys) sys.setdefaultencoding("utf-8") clazz = getPluginClass() o = clazz() d = Device("920121a870e384dd") z = ZDevice("920121a870e384dd") #d.server.adb.cmd("shell", "am force-stop com.android.chrome").communicate() # 将微信强制停止 screen_d_after = d.dump(compressed=False) # 点击后的屏幕内容 a1 = re.compile(r'\[-?\d*,-?\d*\]') screen_d_after = a1.sub('', screen_d_after) #z.server.install() d.server.adb.cmd("shell", "ime set com.zunyun.zime/.ZImeService").communicate() args = { 'start_time': '16', 'stop_time': '16:10', "repo_information_id": "204", "material_KeyWords_id": "207", "KeyWords_interval": "0", "run_count": "3", "slippage_count": "20",
class AdbDevice(object): hiddenService = 'com.fuhu.settingshelper/.SettingsHelperService' LIST_SYSTEM = 'system' LIST_ALL = 'all' LIST_3RD_PARTY = '3rd' LIST_RECENT = 'recent' orientation = ['natural', 'left', 'upsidedown', 'right'] def __init__(self, serialno=None): self.lock = threading.Semaphore() self.cmd = AdbCmd(serialno) self.serialno = serialno def connect(self): self.d = Device(self.serialno) # self.d, self.serialno = ViewClient.connectToDeviceOrExit(serialno=self.serialno) # self.vc = ViewClient(self.d, self.serialno, compresseddump=False, ignoreuiautomatorkilled=True, autodump=False) def startActivity(self, component): component = component.replace('$', '\$') self.cmd.shell( ['am', 'start', '-n', component, '--activity-clear-task']) def isConnected(self): if self.__getDevices(self.serialno): return True else: return False def listPackages(self): return self.cmd.shell(['pm', 'list', 'package'], output=True) def reboot(self): self.cmd.reboot() def dump(self, compressed=False): return self.d.dump(compressed=compressed).encode('utf-8') @staticmethod def retrieveSelector(point, selectors): shortestDistance = 500000 result = None for selector in selectors: print selector.className bounds = selector.info['bounds'] if point[0] <= bounds['right'] and point[0] >= bounds['left'] and point[1] <= bounds['top'] and point[1] >= \ bounds['bottom']: return selector for selector in selectors: bounds = selector.info['bounds'] distance = ( ((bounds['left'] + bounds['top']) / 2 - point[0])**2 + ((bounds['left'] + bounds['bottom']) / 2 - point[1])**2)**0.5 if shortestDistance > distance: shortestDistance = distance result = selector return result def checkSamePoint(self, point, info, isLongClick=False): print info if not self.isScreenOn(): self.powerBtn() if self.isLocked(): self.unlock() if len(info) == 2: if self.d.info['currentPackageName'] == info['packageName']: self.cmd.shell(['input', 'tap', str(point[0]), str(point[1])]) return {'answer': True, 'reason': 'it is the navigation bar'} if info['content-desc'] != '': self.d(contentDescription=info['content-desc']) return {'answer': True, 'reason': 'find by description'} if info['text'] != '': self.d(text=info['text']).click() return {'answer': True, 'reason': 'find by text'} currentViewMap = self.getTouchViewInfo(point) if currentViewMap: if currentViewMap['package'] == info['package']: if currentViewMap['class'] == info['class']: self.d.click(point[0], point[1]) return {'answer': True, 'reason': 'Find the similar view'} else: return { 'answer': False, 'reason': 'the view doesn\'t be found.' } else: return {'answer': False, 'reason': 'In the wrong page'} else: return {'answer': False, 'reason': 'the view can\'t be found.'} @staticmethod def removeKey(d, keys): r = dict(d) for k in keys: if r.has_key(k): del r[k] return r def __getDevices(self, serial): outputRE = re.compile(serial) devices = outputRE.findall(AdbCmd.devices()) if len(devices) > 0: return devices[0] def getTouchViewInfo(self, point, compressed=False): smallestArea = sys.maxint result = None root = ET.fromstring(self.dump(compressed=compressed)) for node in root.iter('node'): bounds = re.match( '\[(?P<x1>[\d]+),(?P<y1>[\d]+)\]\[(?P<x2>[\d]+),(?P<y2>[\d]+)\]', node.get('bounds')) isInclude, area = self._parseRange( point, (int(bounds.group('x1')), int(bounds.group('y1'))), (int(bounds.group('x2')), int(bounds.group('y2')))) if isInclude: if area <= smallestArea: smallestArea = area result = node if result is not None: return result.attrib elif point[1] > self.d.info['displayHeight']: p = { 'packageName': self.d.info['currentPackageName'], 'type': 'Navigation Bar' } return p @staticmethod def getBoundsCenter(bounds): bounds = re.match( '\[(?P<x1>[\d]+),(?P<y1>[\d]+)\]\[(?P<x2>[\d]+),(?P<y2>[\d]+)\]', bounds) x = (int(bounds.group('x2')) + int(bounds.group('x1'))) / 2 y = (int(bounds.group('y2')) + int(bounds.group('y1'))) / 2 return x, y @staticmethod def _parseRange(point, point1, point2): if point[0] >= point1[0] and point[0] <= point2[0]: if point[1] >= point1[1] and point[1] <= point2[1]: area = (point2[0] - point1[0]) * (point2[1] - point1[1]) return (True, area) else: return (False, None) else: return (False, None) def viewFilter(self, view): if view.getClass() == self.viewClass: return True else: return False def screenOn(self, status): if status == True: self.d.screen.on() else: self.d.screen.off() def clearLog(self): self.cmd.shell(['logcat', '-c']) def longClick(self, x, y, duration): if y <= self.d.info['displayHeight']: self.d.swipe(x, y, x, y, steps=duration / 10) else: self.cmd.shell(['input', 'tap', str(x), str(y)]) def click(self, x, y): if y <= self.d.info['displayHeight']: self.d.click(x, y) else: self.cmd.shell(['input', 'tap', str(x), str(y)]) def drag(self, x, y, duration): self.d.drag(x[0], x[1], y[0], y[1], steps=duration / 10) def swipe(self, x, y, duration): self.cmd.shell([ 'input', 'swipe', str(x[0]), str(x[1]), str(y[0]), str(y[1]), str(duration) ]) def type(self, text): translate = re.sub(r'([#\(\)\&\*\'\\\"\~\`\|\<\>?\;])', r'\\\1', text) self.cmd.shell(['input', 'text', translate]) # self.d(className="android.widget.EditText").set_text(text) def hideKeyboard(self): if self.isKeyboardShown(): self.backBtn() def unlock(self): if self.isLocked(): self.menuBtn() def isLocked(self): lockScreenRE = re.compile('mShowingLockscreen=(true|false)') m = lockScreenRE.search(self.cmd.dumpsys(['window', 'policy'])) if m is not None: return m.group(1) == 'true' def isScreenOn(self): screenOnRE = re.compile('mScreenOnFully=(true|false)') m = screenOnRE.search(self.cmd.dumpsys(['window', 'policy'])) if m is not None: return m.group(1) == 'true' def powerBtn(self): self.cmd.inputKeyevnt('POWER') def backBtn(self): self.cmd.inputKeyevnt('BACK') def homeBtn(self): self.cmd.inputKeyevnt('HOME') def menuBtn(self): self.cmd.inputKeyevnt('MENU') # def rotate(self, orient): # if orient == 'auto': # self.d.freeze_rotation(False) # elif orient == '0': # self.d.orientation = 'n' # elif orient == '90': # self.d.orientation = 'l' # elif orient == '180': # self.d.freeze_rotation(True) # self._setScreenOrient(2) # elif orient == '270': # self.d.orientation = 'r' def rotate(self, orient): self.d.freeze_rotation(True) index = self.orientation.index(self.d.orientation) if orient == 'left': index -= 1 if index < 0: self._setScreenOrient(len(self.orientation) - 1) else: self._setScreenOrient(index) elif orient == 'right': index += 1 if index >= len(self.orientation): self._setScreenOrient(0) else: self._setScreenOrient(index) def volumeUp(self): self.cmd.inputKeyevnt('VOLUME_UP') def volumeDown(self): self.cmd.inputKeyevnt('VOLUME_DOWN') # def _setAutoRotate(self, status): # if status: # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:1']) # time.sleep(1) # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:1']) # # else: # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:0']) # time.sleep(1) # self.cmd.shell(['content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:accelerometer_rotation', # '--bind', 'value:i:0']) def _setScreenOrient(self, orient): self.cmd.shell([ 'content', 'insert', '--uri', 'content://settings/system', '--bind', 'name:s:user_rotation', '--bind', 'value:i:' + str(orient) ]) def resetPackage(self, package): self.cmd.shell(['pm', 'clear', package]) def takeSnapshot(self, path): return self.d.screenshot(path) def getCurrDisplay(self): output = self.cmd.dumpsys(['display']) match = re.search( 'mCurrentOrientation=(?P<orientation>[\d])[\w\d\s\(\),-=]+' + 'mCurrentDisplayRect=Rect\(0, 0 - (?P<width>[\d]+),\s+(?P<height>[\d]+)', output) width = int(match.group('width')) height = int(match.group('height')) orientation = int(match.group('orientation')) mode = 'landscape' if width > height else 'portrait' return { 'width': width, 'height': height, 'orientation': orientation, 'mode': mode } def getRealDisplay(self): output = self.cmd.dumpsys(['display']) match = re.search('real\s(?P<width>[\d]+)\sx\s(?P<height>[\d]+)', output) return { 'width': int(match.group('width')), 'height': int(match.group('height')) } def getProp(self, propType=None): if propType: return self.cmd.shell(['getprop', propType], output=True).strip('\n') else: return self.cmd.shell(['getprop'], output=True).strip('\n') def uninstall(self, package): self.cmd.uninstall(package) def install(self, name): self.cmd.install(name) def close(self): pass def checkConnected(self): return self.d.checkConnected() def extractComponentName(self, packageName): if packageName == 'com.google.android.youtube': return 'com.google.android.youtube/.app.honeycomb.Shell$HomeActivity' output = self.cmd.dumpsys(['package', packageName]) try: if os.name == 'nt': splitOutput = output.split('\r\r\n') else: splitOutput = output.split('\r\n') num = splitOutput.index( next(x for x in splitOutput if x.find('android.intent.action.MAIN:') != -1)) if num != -1: print splitOutput[num + 1] return splitOutput[num + 1].split()[1] else: return None except: return None def screenTimeout(self): timeout = self.cmd.getSettings(['system', 'screen_off_timeout']) return long(timeout) / 1000 def setScreenTimeout(self, value): self.cmd.putSettings(['system', 'screen_off_timeout', value]) def isNfcOn(self): match = re.search('mState=(on|off)', self.cmd.dumpsys(['nfc'])) if match: if match.group(1) == 'on': return True else: return False else: return False def isAirPlaneModeOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'airplane_mode_on'])) if match: if match.group(1) == '1': return True else: return False def isInstallUnknownSources(self): match = re.search( '(0|1)', self.cmd.getSettings(['global', 'install_non_market_apps'])) if match: if match.group(1) == '1': return True else: return False def isKeyboardShown(self): output = self.cmd.dumpsys(['input_method']) result = re.search('mInputShown=(true|false)', output) if result.group(1) == 'true': return True else: return False def isWifiOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'wifi_on'])) if match: if match.group(1) == '1': return True else: return False def isBtOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'bluetooth_on'])) if match: if match.group(1) == '1': return True else: return False def isNoKeepActivityOn(self): match = re.search( '(0|1)', self.cmd.getSettings(['global', 'always_finish_activities'])) if match: if match.group(1) == '1': return True else: return False def isDataRoamingOn(self): match = re.search('(0|1)', self.cmd.getSettings(['global', 'data_roaming'])) if match: if match.group(1) == '1': return True else: return False def isAutoRotateOn(self): match = re.search( '(0|1)', self.cmd.getSettings(['system', 'accelerometer_rotation'])) if match: if match.group(1) == '1': return True else: return False def isGpsOn(self): state = self.cmd.getSettings(['secure', 'location_providers_allowed']) if state == 'none': return False else: return True def isAutoBrightnessOn(self): match = re.search( '(0|1)', self.cmd.getSettings(['system', 'screen_brightness_mode'])) if match: if match.group(1) == '1': return True else: return False def isVibrateWhenRingOn(self): match = re.search( '(0|1)', self.cmd.getSettings(['system', 'vibrate_when_ringing'])) if match: if match.group(1) == '1': return True else: return False else: return False def isWindowAniOn(self): match = re.search( '(0.0|1.0)', self.cmd.getSettings(['global', 'window_animation_scale'])) if match: if match.group(1) == '0.0': return True else: return False else: return False def isTransitionAnuOn(self): match = re.search( '(0.0|1.0)', self.cmd.getSettings(['global', 'transition_animation_scale'])) if match: if match.group(1) == '0.0': return True else: return False else: return False def isDurationAniOn(self): match = re.search( '(0.0|1.0)', self.cmd.getSettings(['global', 'animator_duration_scale'])) if match: if match.group(1) == '0.0': return True else: return False else: return False def enableWifi(self, state): if state: self.cmd.shell([ 'am', 'startservice', '--ez', 'wifi', 'true', '-n', self.hiddenService ]) else: self.cmd.shell([ 'am', 'startservice', '--ez', 'wifi', 'false', '-n', self.hiddenService ]) def enableBluetooth(self, state): if state: self.cmd.shell([ 'am', 'startservice', '--ez', 'bt', 'true', '-n', self.hiddenService ]) else: self.cmd.shell([ 'am', 'startservice', '--ez', 'bt', 'false', '-n', self.hiddenService ]) def enableInstallUnknownSources(self, state): if state: self.cmd.putSettings(['global', 'install_non_market_apps', '1']) else: self.cmd.putSettings(['global', 'install_non_market_apps', '0']) def enableNfc(self, state): if state: self.cmd.shell(['service', 'call', 'nfc', '6']) else: self.cmd.shell(['service', 'call', 'nfc', '5']) def enableNoKeepActivity(self, state): if state: self.cmd.putSettings(['global', 'always_finish_activities', '1']) else: self.cmd.putSettings(['global', 'always_finish_activities', '0']) def enableDataRoaming(self, state): if state: self.cmd.putSettings(['global', 'data_roaming', '1']) else: self.cmd.putSettings(['global', 'data_roaming', '0']) def enableAutoRotate(self, state): if state: self.cmd.putSettings(['system', 'accelerometer_rotation', '1']) else: self.cmd.putSettings(['system', 'accelerometer_rotation', '0']) def enableGps(self, state): if state: self.cmd.putSettings( ['secure', 'location_providers_allowed', 'gps,network']) else: self.cmd.putSettings( ['secure', 'location_providers_allowed', 'none']) def enableAutoBrightness(self, state): if state: self.cmd.putSettings(['system', 'screen_brightness_mode', '1']) else: self.cmd.putSettings(['system', 'screen_brightness_mode', '0']) def enableVibrateRinging(self, state): if state: self.cmd.putSettings(['system', 'vibrate_when_ringing', '1']) else: self.cmd.putSettings(['system', 'vibrate_when_ringing', '0']) def enableVibrateWhenRing(self, state): if state: self.cmd.putSettings(['system', 'vibrate_when_ringing', '1']) else: self.cmd.putSettings(['system', 'vibrate_when_ringing', '0']) def enableWindowAnimator(self, state): if state: self.cmd.putSettings(['global', 'window_animation_scale', '1.0']) else: self.cmd.putSettings(['global', 'window_animation_scale', '0.0']) def enableTransitionAnimator(self, state): if state: self.cmd.putSettings( ['global', 'transition_animation_scale', '1.0']) else: self.cmd.putSettings( ['global', 'transition_animation_scale', '0.0']) def enableDurationAnimation(self, state): if state: self.cmd.putSettings(['global', 'animator_duration_scale', '1.0']) else: self.cmd.putSettings(['global', 'animator_duration_scale', '0.0']) def enableAirplaneMode(self, state): if state: self.cmd.putSettings(['global', 'airplane_mode_on', '1']) self.cmd.shell([ 'am', 'broadcast', '-a', 'android.intent.action.AIRPLANE_MODE', '--ez', 'state', 'true' ]) else: self.cmd.putSettings(['global', 'airplane_mode_on', '0']) self.cmd.shell([ 'am', 'broadcast', '-a', 'android.intent.action.AIRPLANE_MODE', '--ez', 'state', 'false' ]) def requestPackage(self, t): result = None if t == self.LIST_ALL: result = self.cmd.shell(['pm', 'list', 'packages'], output=True) elif t == self.LIST_SYSTEM: result = self.cmd.shell(['pm', 'list', 'packages', '-s'], output=True) elif t == self.LIST_3RD_PARTY: result = self.cmd.shell(['pm', 'list', 'packages', '-3'], output=True) if result: packages = result.split('\r\n') packages.remove('') packages.sort() return packages def getSerialNumber(self): return self.serialno
# dict_w['title'] = res_tit # dict_w['tag'] = 'description' # else: # lstResult = tv(resourceId = 'com.xiaomi.voicecontrol:id/lstResult') # result_count = lstResult.childCount # res_tit_list = [] # for t in range(result_count): # print t, # res_tit = lstResult.child(resourceId = 'com.xiaomi.voicecontrol:id/titleBar',instance = t).child(resourceId = 'com.xiaomi.voicecontrol:id/title').text # print res_tit, # res_tit_list.append(res_tit) # dict_w['title'] = res_tit_list # dict_w['tag'] = 'result_list' # dict_w['recognition'] = tv(resourceId = 'com.xiaomi.voicecontrol:id/title').text # dict_w['result_msg'] = tv(resourceId = 'com.xiaomi.voicecontrol:id/txtTitle').text tv.dump("%s.xml" % (f_name)) print "\tDump... " screencapAndPullOut(f_name + ".png") tv.press('back') print "Done.\n*-*-*-*-*-*-*-*-*-*-*-*-*-*-" except: # dict_w['tag'] = 'occur_err' print "occur_err" pass # f_result.write(str(dict_w).encode('utf-8')) query = f_query.readline() if os.path.exists(f_name + ".png") and os.path.exists(f_name + ".xml"): pass else: f_fail = open(f_name + ".txt", 'w') f_fail.close()
class TfTravel(object): def __init__(self): self.d = Device() self.Q = collections.OrderedDict() self.stats = 0 # 0 本界面,1新界面 self.package = "com.android.deskclock" self.mainpagemd5, self.mainpagenode = self.parserxml() # logging.basicConfig(level=logging.DEBUG, # format='%(asctime)s %(levelname)s: %(message)s') def performaction(self, act=Actions.CLICK, para=(100, 200)): if act == Actions.CLICK: self.d.click(para[0], para[1]) self.d.wait.idle() time.sleep(1) elif act == Actions.BACK: self.d.press.back() return self.parserxml() def returnmd5(self, str): md5str = str m1 = hashlib.md5() m1.update(md5str.encode("utf-8")) token = m1.hexdigest() return token def getxml(self): t = self.d.dump(filename=None, compressed=False) # with open("test.xml") as f: # t = f.read() DOMTree = xml.dom.minidom.parseString(t.encode("utf-8")) Data = DOMTree.documentElement nodes = Data.getElementsByTagName("node") return nodes # 解析xml,返回页面所有节点[((y,x),nodemd5)]/页面MD5 def parserxml(self): pagestr = "" nodes_list = [] # collections.OrderedDict() nodes = self.getxml() for i in nodes: bound = i.getAttribute('bounds').strip() classname = i.getAttribute('class').strip() text = i.getAttribute('text').strip() resourceid = i.getAttribute('resource-id').strip() package = i.getAttribute('package').strip() if classname not in BLACK_CLASS and resourceid not in BLACK_RESOURCE and text not in BLACK_TEXT and package == self.package: # 过滤节点,获取可操作bounds _ = bound.replace("][", ",").replace("bounds=", "").replace("\"", "") __ = _.replace("[", "").replace("]", "").split(",") # box = (int(__[0]), int(__[1]), int(__[2]), int(__[3])) x = int(__[0]) + (int(__[2]) - int(__[0])) / 2 y = int(__[1]) + (int(__[3]) - int(__[1])) / 2 box = (y, x) if box not in nodes_list: # nodes_list[box] = {} nodes_list.append(box) pagestr = pagestr + classname + resourceid + bound + text nodes_list.sort(reverse=False) # sorted_nodes_list = sorted(nodes_list.items(), key=operator.itemgetter(0)) # 按照Y-X 排序 pagemd5 = self.returnmd5(pagestr) return pagemd5, nodes_list def compareblack(self): if len(self.cycle) == 3 and self.cycle[0] == self.cycle[1] and self.cycle[1] == self.cycle[2]: self.cycle = [] return True return False def startstravel(self): # #pagecontainer={mainpagemd5:mainpagenode} for i in self.mainpagenode: clicknode = i self.mainpagenode.remove(i) click = clicknode[0] print "move clicknode:", clicknode self.performaction(act=Actions.CLICK, para=(click[1], click[0])) time.sleep(1) subpagemd5, subpagenode = self.parserxml() if subpagemd5 != self.mainpagemd5: self.mainpagenode.append(clicknode) # if self.compareblack(): # mainpagenode.remove(clicknode) self.startstravel() # subpagenode, subpagemd5 = self.parserxml() # click = i.get(subpagemd5) # self.performaction(act=Actions.CLICK, para=(click[1], click[0])) # subpagenode, subpagemd5 = self.parserxml() # if subpagemd5 not in pagecontainer: # pagecontainer[subpagemd5] = subpagenode # else: # pagecontainer.get() def looptravel(self): popclick = () container = {self.mainpagemd5: self.mainpagenode} lastpage = self.mainpagenode lastpagemd5 = self.mainpagemd5 while True: nowpagemd5, nowpage = self.parserxml() print nowpagemd5, lastpagemd5 if nowpagemd5 != lastpagemd5: # 进入不同的页面 if nowpagemd5 not in container: container[nowpagemd5] = nowpage self.stats = 1 else: self.stats = 0 if self.stats == 0: # 如果在本界面: pass elif self.stats == 1: # 如果新界面: # 如果返回了一个已经存在的界面,说明是返回的,要去掉这个返回键 if nowpagemd5 not in container: lastpage.insert(0, popclick) if popclick not in container.get(lastpagemd5): container.get(lastpagemd5).insert(0, popclick) if len(container.get(nowpagemd5)) > 0: popclick = container.get(nowpagemd5).pop(0) self.performaction(act=Actions.CLICK, para=(popclick[1], popclick[0])) time.sleep(1) lastpage, lastpagemd5 = nowpage, nowpagemd5 lastpopclick = popclick def performclick(self, x, y): self.performaction(act=Actions.CLICK, para=(x, y)) return self.parserxml() def looptravel1(self): container = self.mainpagenode oldmd5 = self.mainpagemd5 oldpage = self.mainpagenode tree = container for i in xrange(len(self.mainpagenode)): click = container[i] nowpagemd5, nowpage = self.performaction(act=Actions.CLICK, para=(click[1], click[0])) if nowpagemd5 != oldmd5: container[i] = [i] + nowpage for j in xrange(len(nowpage)): self.looptravel2(nowpagemd5, nowpage[j]) def looptravel2(self, md5, node): nowpagemd5, nowpage = self.performaction(act=Actions.CLICK, para=(node[1], node[0])) if nowpagemd5 != md5:#new world return nowpagemd5, nowpage else: return None
class AndroidDevice(object): def __init__(self): self.device = None self.call_status = None self.d = None def select_device(self, device=1): list_devices = check_list() if list_devices: if device <= 0 or device > len(list_devices): print(NO_SELECTED) exit() else: self.device = list_devices[device - 1].split()[0].decode('utf-8') self.d = Device(self.device) return self.device else: print(NO_CONNECTED) exit() def dial_number(self, number): if self.device: check_call([ 'adb', '-s', self.device, 'shell', 'am', 'start', '-a', 'android.intent.action.CALL', '-d', 'tel:{0}'.format(number) ]) self.call_status = CALLING def hang_up(self): if self.call_status == CALLING: check_call(['adb', 'shell', 'input', 'keyevent 6']) self.call_status = None def adb_open_settings(self): check_call( ['adb', 'shell', 'am', 'start', '-a', 'android.settings.SETTINGS']) def turn_on_wifi(self): check_call(['adb', '-s', self.device, 'shell', 'svc wifi enable']) def turn_off_wifi(self): check_call(['adb', '-s', self.device, 'shell', 'svc wifi disable']) def adb_calling_test(self, number, delay=5): self.dial_number(number) time.sleep(delay) self.hang_up() def adb_wifi_test(self, on_off): if on_off == 'ON': self.turn_on_wifi() elif on_off == 'OFF': self.turn_off_wifi() def uiaviewer_generator(self, name_file): self.d.screenshot('{0}.png'.format(name_file)) self.d.dump('{0}.uix'.format(name_file)) def initial_state(self): self.d.screen.on() self.d.press.home() def type_number(self, number): for digit in number: self.d(text='{0}'.format(digit), className='android.widget.TextView').click() def uia_calling_test(self, number, delay=2): self.initial_state() flag = False if self.d(descriptionContains='Phone', className='android.widget.TextView').count == 1: self.d(descriptionContains='Phone', className='android.widget.TextView').click() # self.d(descriptionContains='key pad', className='android.widget.ImageButton').click() self.type_number(number) self.d(descriptionContains='dial', className='android.widget.ImageButton').click() time.sleep(delay) if self.d(descriptionContains='Phone', className='android.widget.TextView').count == 1: self.d(descriptionContains='End', className='android.widget.ImageButton').click() elif self.d(descriptionContains='Teléfono', className='android.widget.TextView').count == 1: self.d(descriptionContains='Teléfono', className='android.widget.TextView').click() self.d(descriptionMatches='teclado', className='android.widget.ImageButton').click() self.d(descriptionMatches='', className='android.widget.EditText').click() self.type_number(number) self.d(descriptionMatches='marcar', className='android.widget.ImageButton').click() time.sleep(delay) self.d(descriptionMatches='Finalizar llamada', className='android.widget.ImageButton').click() def quick_turn_on_wifi(self): status = self.d(descriptionContains='Wi-Fi', className='android.widget.Switch').checked if not status: self.d(descriptionContains='Wi-Fi', className='android.widget.Switch').click() else: print('WiFi actalmente encendido') def quick_turn_off_wifi(self): status = self.d(descriptionContains='Wi-Fi', className='android.widget.Switch').checked if status: self.d(descriptionContains='Wi-Fi', className='android.widget.Switch').click() else: print('WiFi actualmente apagado') def uia_quick_wifi_test(self, on_off): self.d.open.quick_settings() time.sleep(3) if on_off == 'ON': self.quick_turn_on_wifi() elif on_off == 'OFF': self.quick_turn_off_wifi() time.sleep(3) self.initial_state() def setting_turn_on_wifi(self): status = self.d(index='2', className='android.widget.Switch').checked if (status == False): self.d(index='2', className='android.widget.Switch').click() else: print('WiFi actalmente encendido') def setting_turn_off_wifi(self): status = self.d(index='2', className='android.widget.Switch').checked if status: self.d(index='2', className='android.widget.Switch').click() else: print('WiFi actualmente apagado') def setting_turn_ES_wifi(self): status = self.d(text='Sí', className='android.widget.Switch').checked if status: self.d(text='Sí', className='android.widget.Switch').click() else: print('WiFi actualmente apagado') def settings_wifi_test(self, on_off): self.initial_state() self.adb_open_settings() flag = False try: flag = self.d(text='Wireless & networks', className='android.widget.TextView').checked flag = True except: flag = False if flag: self.d(text='Wireless & networks', className='android.widget.TextView').click() if on_off == 'ON': self.d(text='Wi-Fi', className='android.widget.TextView').click() self.setting_turn_on_wifi() elif on_off == 'OFF': self.d(text='Wi-Fi', className='android.widget.TextView').click() self.setting_turn_off_wifi() time.sleep(3) self.d.press.home() else: self.d(text='Internet y red', className='android.widget.TextView').click() if on_off == 'ON': self.setting_turn_on_wifi() elif on_off == 'OFF': self.setting_turn_ES_wifi() time.sleep(3) self.d.press.home() def adb_claculator_SendText(self, number, delay=5): self.dial_calculator() time.sleep(3) self.dial_calculator_enter(number) time.sleep(delay) self.hang_up() def dial_calculator(self): if self.device: check_call( ['adb', 'shell', 'monkey -p', 'com.android.calculator2', '1']) def dial_calculator_enter(self, number): if self.device: check_call( ['adb', 'shell', 'input text', '\'' + number + '\'', '']) def ui_calculator(self, number, delay=5): self.initial_state() flag = False self.d(descriptionContains='Apps', className='android.widget.TextView').click() #self.d.swipe(500, 1500, 500, 200, 3) time.sleep(1) self.d(descriptionMatches='Calculator', className='android.widget.TextView').click() self.type_number_calculator(number) self.d(descriptionContains='equals', className='android.widget.ImageView').click() def type_number_calculator(self, number): for digit in number: numbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] character = '{0}'.format(digit) if (character in numbers): self.d(text=character, className='android.widget.Button').click() else: if (character == 'X' or character == 'x' or character == '*'): character = 'multiply' elif (digit == '/'): character = 'divide' elif (digit == '-'): character = 'minus' elif (digit == '+'): character = 'plus' self.d(descriptionContains=character, className='android.widget.ImageView').click()
:return: ''' dom = parseString(xml_data.encode("utf-8")) nodes = dom.getElementsByTagName('node') for node in nodes: if node.hasAttribute('resource-id'): return xml_data else: break bounds2ids = ViewClientHandler.dump_view_server(package) if bounds2ids == None: ViewClientHandler.logger.error('Cannot identify the package!') return xml_data ViewClientHandler.logger.info(str(bounds2ids)) for node in nodes: if node.getAttribute('bounds') in bounds2ids: node.setAttribute('resource-id', bounds2ids[node.getAttribute('bounds')]) else: ViewClientHandler.logger.warn('Cannot find ' + node.getAttribute('bounds')) return dom.toxml() if __name__ == '__main__': dev = Device() print ViewClientHandler.fill_ids(dev.dump(), 'com.kuaihuoyun.driver')
def main(): port = '5554' d = Device('emulator-' + port) #d.dump("/home/yu/repeatbugreport/middleResults/result.xml") #this is for flash d(resourceId="com.example.terin.asu_flashcardapp:id/email").set_text( "*****@*****.**") d(resourceId="com.example.terin.asu_flashcardapp:id/password").set_text( "12331986") d(resourceId="com.example.terin.asu_flashcardapp:id/email_sign_in_button" ).click() time.sleep(4) ''' #this is for yastore d(resourceId="android:id/text1").click(); d(resourceId="com.github.yeriomin.yalpstore:id/email").set_text("*****@*****.**") d(resourceId="com.github.yeriomin.yalpstore:id/password").set_text("lunar1986") d(resourceId="com.github.yeriomin.yalpstore:id/button_ok").click(); time.sleep(4) ''' '''this is for mifos d(resourceId="com.mifos.mifosxdroid:id/et_username").set_text("mifos") d(resourceId="com.mifos.mifosxdroid:id/et_password").set_text("password") d(text="LOGIN").click(); time.sleep(2) ''' #d(text="ALLOW").click(); #d.press.back() #d.press.home() d.orientation = "n" d.screen.on() #address='/home/yu/repeatbugreport' address = '.' doc = minidom.parse(address + '/middleResults/run.xml') root = doc.documentElement for step in root.childNodes: if step.nodeType == minidom.Node.ELEMENT_NODE: ##minidom is a little bit ugly textid = "" textX = "" textY = "" textStr = "" actionTypes = step.getElementsByTagName("Actiontype") if actionTypes[0].firstChild.nodeValue == "Noaction": continue if actionTypes[0].firstChild.nodeValue == "back": d.press.back() continue if actionTypes[0].firstChild.nodeValue == "enter": d.press("enter") time.sleep(2) continue ##########get the source id ownText = step.getElementsByTagName("ownText") if ownText.length != 0: textid = ownText[0].firstChild.nodeValue #########get the x-position and y-position xPositions = step.getElementsByTagName("xposition") yPositions = step.getElementsByTagName("yposition") if xPositions.length != 0: textX = xPositions[0].firstChild.nodeValue textY = yPositions[0].firstChild.nodeValue #########get the click text clickText = step.getElementsByTagName("clickText") if clickText.length != 0: if clickText[0].childNodes.length != 0: textStr = clickText[0].firstChild.nodeValue #print(actionTypes[0].firstChild.nodeValue) if actionTypes[0].firstChild.nodeValue == "EditText": typewhat = step.getElementsByTagName("typeWhat") textTypeWhat = typewhat[0].firstChild.nodeValue if textTypeWhat == "default": continue #write text d(resourceId=textid).set_text(textTypeWhat) #d.press("enter") #print(textid) #print(textTypeWhat) #d(resourceId="com.newsblur:id/login_password").set_text("asd") #d.wait.idle() time.sleep(0.5) else: #elif actionTypes[0].firstChild.nodeValue=="ClickList": #########get the x-position and y-position clicktype = step.getElementsByTagName("clicktype") textclicktype = clicktype[0].firstChild.nodeValue try: if textclicktype == "short": if not textid == "": d(resourceId=textid).click() if not textStr == "": d(text=textStr).click() else: d.click(int(textX), int(textY)) elif textclicktype == "long": if not textid == "": d(resourceId=textid).long_click() elif not textStr == "": d(text=textStr).long_click() else: d.long_click(int(textX), int(textY)) #d.wait.update() except Exception as err: break time.sleep(2) #d.dump("/home/yu/repeatbugreport/middleResults/result.xml") d.dump(address + "/middleResults/result.xml") cmd = "adb -s emulator-" + port + " shell dumpsys window windows | grep -E 'mFocusedApp'" packInfo = commands.getstatusoutput(cmd) fo = open(address + "/middleResults/packInfo", "w") fo.write(str(packInfo)) fo.close() if root.getAttribute("Rotate") == "True": d.orientation = "l" time.sleep(0.5) d.orientation = "n" time.sleep(0.5)
filehandler = logging.FileHandler(dir_data + '/UiDroid-Console.log') filehandler.setLevel(logging.DEBUG) logger.addHandler(filehandler) filehandler.setFormatter(formatter) #time.sleep(30) ui_interact() flag = False except: pass # dev.screenshot(dir_data + current_time + ".png") os.system('adb -s ' + series + ' shell /system/bin/screencap -p /sdcard/screenshot.png') os.system('adb -s ' + series + ' pull /sdcard/screenshot.png ' + dir_data) try: dev.dump(dir_data + current_time + "hierarchy.xml") except: print 'except xml' logger.info('screen shot at ' + current_time) dev.screen.on() dev.press.home() #time.sleep(20) #package_list = os.popen('adb -s ' + series + ' shell cat /data/system/packages.list') #logger.info(package_list.readlines()) #ps_list = os.popen('adb -s ' + series + ' shell ps') #logger.info(ps_list.readlines()) os.popen('adb -s ' + series + ' shell am force-stop ' + package) os.popen('adb -s ' + series + ' uninstall ' + package) logger.info('uninstall')
__author__ = "Neil" __time__ = "2018/6/1 21:17" from uiautomator import Device import time d = Device('192.168.181.101:5555', adb_server_host='localhost', adb_server_port=5037) d.dump("hierarchy.xml") def clickText(arr): for each in arr: d(text=each).click() time.sleep(1.5) d.press.back() time.sleep(0.5) items = [ "校园网络", "场馆预约", "图书馆", "成绩查询", "课外研学", "校车助手", "校历查询", "权益服务", "空教室", "跑操助手", "教务通知" ] clickText(items) d.swipe(89, 1000, 89, 500) items = ["课表助手", "实验助手", "考试助手", "人文讲座", "校园活动"] clickText(items)
class ModelInfo(): ''' classdocs ''' def __init__(self, deviceserial): ''' Constructor ''' #sndLog = CLS("test", "test") self.osType = sys.platform self.mstrInfo = {} #self.devSerials = self.instAdb.device_serial() self.mstrDevice = Device(deviceserial) self.mstrInfo = self.mstrDevice.info ''' DEVICE Infoamtions { u'displayRotation': 0, u'displaySizeDpY': 640, u'displaySizeDpX': 360, u'currentPackageName': u'com.android.launcher', u'productName': u'takju', u'displayWidth': 720, u'sdkInt': 18, u'displayHeight': 1184, u'naturalOrientation': True } ''' def getCurrntProductInfo(self): return self.mstrInfo def getProductNmae(self): return self.mstrInfo['productName'] def getCurrntPkg(self): return self.mstrInfo['currentPackageName'] def getSDKInt(self): return self.mstrInfo['sdkInt'] def getRotation(self): return self.mstrInfo['displayRotation'] def getNaturalOri(self): return self.mstrInfo['naturalOrientation'] def getDisplayState(self): return self.mstrDevice.screen def setReflash(self): pass #define Key activity def setDevScrnOn(self): self.mstrDevice.screen.on() def setMstDevScrnOff(self): self.mstrDevice.screen.off() def setWakeup(self): self.mstrDevice.wakeup() def setSleep(self): self.mstrDevice.sleep() #Hard key Soft key def pressHome(self): return self.mstrDevice.press.home() def pressBack(self): return self.mstrDevice.press.back() ###################################################################### def pressLeft(self): return self.mstrDevice.press.left() def pressRight(self): return self.mstrDevice.press.right() def pressUp(self): return self.mstrDevice.press.up() def pressDown(self): return self.mstrDevice.press.down() def pressCenter(self): return self.mstrDevice.press.center() ###################################################################### def pressMenu(self): return self.mstrDevice.press.menu() def pressSearch(self): return self.mstrDevice.press.search() def pressEnter(self): return self.mstrDevice.press.enter() def pressDelete(self): return self.mstrDevice.press.delete() # or del def pressRecent(self): return self.mstrDevice.press.recent() def pressVol_Up(self): return self.mstrDevice.press.volume_up() def pressVol_Down(self): return self.mstrDevice.press.volume_down() def pressVol_Mute(self): return self.mstrDevice.press.volume_mute() def pressPower(self): return self.mstrDevice.press.power() def clik(self, x, y): return self.mstrDevice.click(x, y) def longClik(self, x, y): ''' Description: param: x, y : start first point x, y return : Boolean ''' return self.mstrDevice.long_click(x, y) def swipe(self, sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.swipe(sx, sy, ex, ey, steps) def drage(self, sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.drag(sx, sy, ex, ey, steps) #screen action of the device def setOrientation(self, scrAct='natural', choiceDevice='mstr'): ''' Description param d.orientation = 'l' or 'left' d.orientation = 'r' or 'right' d.orientation = 'n' or 'natural' return : None ''' self.mstrDevice.orientation = scrAct def setFreezeRotation(self, condition=False, choiceDevice='mstr'): ''' param: condition : False un-freeze rotation return : None ''' self.mstrDevice.freeze_rotation(condition) def takeScreenShot(self, choiceDevice='mstr'): ''' Description: take screenshot and save to local file 'home.png' can work until android 4.2 param image name ''' def dumpWindowHeirarchy(self, filename='./log/hierachy.xml'): return self.mstrDevice.dump(filename) def dumpWindowHeirarchyStream(self): return self.mstrDevice.dump() def notification(self): ''' Open notification, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.Notification() def quickSettings(self): ''' open quick settins, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.quick_settings() def waitidle(self): ''' wait for current window to idle return : None ''' self.mstrDevice.wait.idle() def waitWindowUpdate(self): ''' wait until window upate event occurs return : Boolean ''' self.mstrDevice.wait.update() def getCurrentActivityInfo(self, text): ''' INFOMATION: { u'contentDescription': u'', u'checked': False, u'scrollable': False, u'text': u'Settings', u'packageName': u'com.android.launcher', u'selected': False, u'enabled': True, u'bounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'className': u'android.widget.TextView', u'focused': False, u'focusable': True, u'clickable': True, u'chileCount': 0, u'longClickable': True, u'visibleBounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'checkable': False } ''' return self.mstrDevice(text).info def uiObjExist(self, text): ''' ture if exists, else False ''' return self.mstrDevice.exists(text) def watcher(self): pass def handler(self): pass def selector(self): pass def __del__(self): pass
# d(text="changer").click() # time.sleep(2) # d(text="Random").click() # time.sleep(1) # d.press('home') d(text="XPrivacy").click() time.sleep(3) d.click(650, 100) time.sleep(1) d.swipe(700, 1000, 700, 500) d(text="Settings").click() time.sleep(1) d(text="Randomize now").click() time.sleep(1) d.swipe(350, 1000, 350, 100) d.dump('aaa') d.swipe(350, 1000, 350, 100) time.sleep(1) d.swipe(350, 1000, 350, 800) d.dump('bbb') d(text="OK").click() list = [17, 20, 23, 26, 31, 36, 39, 42, 45, 48, 55, 66, 69] with open('aaa', 'r') as f: string = f.read() with open('bbb', 'r') as f: string = string + f.read() argudict = {} for i in list:
filehandler.setLevel(logging.DEBUG) logger.addHandler(filehandler) filehandler.setFormatter(formatter) # time.sleep(30) ui_interact() flag = False except: pass # dev.screenshot(dir_data + current_time + ".png") os.system('adb -s ' + series + ' shell /system/bin/screencap -p /sdcard/screenshot.png') os.system('adb -s ' + series + ' pull /sdcard/screenshot.png ' + dir_data) try: dev.dump(dir_data + current_time + "hierarchy.xml") except: print 'except xml' logger.info('screen shot at ' + current_time) dev.screen.on() dev.press.home() # time.sleep(20) # package_list = os.popen('adb -s ' + series + ' shell cat /data/system/packages.list') # logger.info(package_list.readlines()) # ps_list = os.popen('adb -s ' + series + ' shell ps') # logger.info(ps_list.readlines()) os.popen('adb -s ' + series + ' shell am force-stop ' + package) os.popen('adb -s ' + series + ' uninstall ' + package) logger.info('uninstall') os.popen('adb -s ' + series + ' logcat -c')
class ModelInfo(): ''' classdocs ''' def __init__(self, deviceserial): ''' Constructor ''' #sndLog = CLS("test", "test") self.osType = sys.platform self.mstrInfo = {} #self.devSerials = self.instAdb.device_serial() self.mstrDevice = Device(deviceserial) self.mstrInfo = self.mstrDevice.info ''' DEVICE Infoamtions { u'displayRotation': 0, u'displaySizeDpY': 640, u'displaySizeDpX': 360, u'currentPackageName': u'com.android.launcher', u'productName': u'takju', u'displayWidth': 720, u'sdkInt': 18, u'displayHeight': 1184, u'naturalOrientation': True } ''' def getCurrntProductInfo(self): return self.mstrInfo def getProductNmae(self): return self.mstrInfo['productName'] def getCurrntPkg(self): return self.mstrInfo['currentPackageName'] def getSDKInt(self): return self.mstrInfo['sdkInt'] def getRotation(self): return self.mstrInfo['displayRotation'] def getNaturalOri(self): return self.mstrInfo['naturalOrientation'] def getDisplayState(self): return self.mstrDevice.screen def setReflash(self): pass #define Key activity def setDevScrnOn(self): self.mstrDevice.screen.on() def setMstDevScrnOff(self): self.mstrDevice.screen.off() def setWakeup(self): self.mstrDevice.wakeup() def setSleep(self): self.mstrDevice.sleep() #Hard key Soft key def pressHome(self): return self.mstrDevice.press.home() def pressBack(self): return self.mstrDevice.press.back() ###################################################################### def pressLeft(self): return self.mstrDevice.press.left() def pressRight(self): return self.mstrDevice.press.right() def pressUp(self): return self.mstrDevice.press.up() def pressDown(self): return self.mstrDevice.press.down() def pressCenter(self): return self.mstrDevice.press.center() ###################################################################### def pressMenu(self): return self.mstrDevice.press.menu() def pressSearch(self): return self.mstrDevice.press.search() def pressEnter(self): return self.mstrDevice.press.enter() def pressDelete(self): return self.mstrDevice.press.delete() # or del def pressRecent(self): return self.mstrDevice.press.recent() def pressVol_Up(self): return self.mstrDevice.press.volume_up() def pressVol_Down(self): return self.mstrDevice.press.volume_down() def pressVol_Mute(self): return self.mstrDevice.press.volume_mute() def pressPower(self): return self.mstrDevice.press.power() def clik(self, x, y): return self.mstrDevice.click(x, y) def longClik(self,x, y): ''' Description: param: x, y : start first point x, y return : Boolean ''' return self.mstrDevice.long_click(x, y) def swipe(self, sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.swipe(sx, sy, ex, ey, steps) def drage(self,sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.drag(sx, sy, ex, ey, steps) #screen action of the device def setOrientation(self,scrAct='natural', choiceDevice='mstr'): ''' Description param d.orientation = 'l' or 'left' d.orientation = 'r' or 'right' d.orientation = 'n' or 'natural' return : None ''' self.mstrDevice.orientation = scrAct def setFreezeRotation(self,condition=False,choiceDevice='mstr'): ''' param: condition : False un-freeze rotation return : None ''' self.mstrDevice.freeze_rotation(condition) def takeScreenShot(self, choiceDevice = 'mstr'): ''' Description: take screenshot and save to local file 'home.png' can work until android 4.2 param image name ''' def dumpWindowHeirarchy(self,filename='./log/hierachy.xml'): return self.mstrDevice.dump(filename) def dumpWindowHeirarchyStream(self): return self.mstrDevice.dump() def notification(self): ''' Open notification, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.Notification() def quickSettings(self): ''' open quick settins, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.quick_settings() def waitidle(self): ''' wait for current window to idle return : None ''' self.mstrDevice.wait.idle() def waitWindowUpdate(self): ''' wait until window upate event occurs return : Boolean ''' self.mstrDevice.wait.update() def getCurrentActivityInfo(self, text): ''' INFOMATION: { u'contentDescription': u'', u'checked': False, u'scrollable': False, u'text': u'Settings', u'packageName': u'com.android.launcher', u'selected': False, u'enabled': True, u'bounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'className': u'android.widget.TextView', u'focused': False, u'focusable': True, u'clickable': True, u'chileCount': 0, u'longClickable': True, u'visibleBounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'checkable': False } ''' return self.mstrDevice(text).info def uiObjExist(self,text): ''' ture if exists, else False ''' return self.mstrDevice.exists(text) def watcher(self): pass def handler(self): pass def selector(self): pass def __del__(self): pass
'http://api.ema666.com/Api/userLogin?uName=wangzeming666&pWord=123456789&Developer=Cnp%2bioCFjIENLUVatRXU6g%3d%3d', timeout=10) token = re.match(r'([\w\W]+?)&', request_token.text).group(1) print(token) number = requests.get( 'http://api.ema666.com/Api/userGetPhone?ItemId=165&token={}&PhoneType=0' .format(token), timeout=10) phonenum = re.match(r'([\d]+);', number.text).group(1) print(phonenum) phonenum86 = '+86' + phonenum os.system( 'adb -s {} shell am start -n biz.bokhorst.xprivacy/biz.bokhorst.xprivacy.ActivityMain' .format(deviceID)) time.sleep(3) d.dump('aaa') d(description='More options').click() time.sleep(1) d(text="Settings").click() time.sleep(1) d.swipe(500, 1700, 500, -500) d(text="Randomize now").click() time.sleep(1) d.dump('aaa') d.swipe(500, 1700, 500, 300) d.dump('bbb') d.swipe(500, 1700, 500, 700) d.dump('ccc') d(description="OK").click() list = [21, 24, 27, 30, 35, 40, 43, 46, 49, 52, 59, 70, 73] with open('aaa', 'r') as f:
class Step(adb_step): """ Description: Base class for all bluetooth test steps """ def __init__(self, **kwargs): adb_step.__init__(self, **kwargs) # parse kwargs if "timeout" in kwargs: self.timeout = kwargs["timeout"] else: self.timeout = 10000 if "serial" in kwargs: self.serial = kwargs["serial"] else: self.serial = None if "no_log" in kwargs: self.no_log = kwargs["no_log"] else: self.no_log = False # constants for pass and error messages if self.serial: self._PASSM = "[ {} ] ".format( self.serial) + self.__class__.__name__ + " - [PASSED]" self._ERRORM = "[ {} ] ".format( self.serial) + self.__class__.__name__ + " - [FAILED]" else: self._PASSM = self.__class__.__name__ + " - [PASSED]" self._ERRORM = self.__class__.__name__ + " - [FAILED]" # defaults pass and error messages self.passm = self._PASSM self.errorm = self._ERRORM # replacing old uidevice available in testlib/external with standard # uiautomator device class self.uidevice = Device(serial=self.serial) # initialize adb connection with below to have backward compatibility self.adb_connection = Adb(serial=self.serial) # Add Common ADB API to use instead of above hereafter self.adb_connection_common = connection_adb(**kwargs) if "version" in kwargs: self.version = kwargs["version"] else: self.version = self.adb_connection_common.get_prop( 'ro.build.version.release') def set_passm(self, pass_string): """ Description: Helps you customize pass message Usage: BtStep.set_passm("BT switch turned on") :param pass_string: custom pass message """ self.passm = self._PASSM + " {}".format(pass_string) def set_errorm(self, particular_string, error_string): """ Description: Helps you customize error message Usage: BtStep.set_errorm("OFF", "Turning off BT failed") :param particular_string: additional error message :param error_string: custom error message """ self.errorm = self._ERRORM + " {} -> {}".format( particular_string, error_string) def log_error_info(self): """ Description: Save test artifacts when test fails """ if self.no_log is False: try: # construct name of file and take screenshot if self.serial: serial_name = "_{}".format(self.serial) else: serial_name = "" base = "%s_%s%s" % (time.strftime("%y-%m-%d_%h:%m:%s"), self.__class__.__name__, serial_name) screenshot_name = os.path.join(self.testlib_log_path, base + ".png") self.take_picture(screenshot_name) dump_file = os.path.join(self.testlib_log_path, base + ".uix") with open(dump_file, "w") as fp: buf = self.uidevice.dump() fp.write(buf.encode("UTF-8", errors="ignore")) except Exception, e: info_message = "Could not get screenshot: {}".format(e.message) if self.serial: info_message = ("[ {} ] " + info_message).format( self.serial) self.logger.info(info_message)
#!/usr/bin/python from uiautomator import Device import sys # get the target device d = Device(sys.argv[1]) # dump ui xml d.dump(sys.argv[2])