How to use _cleanup_forwards method in Airtest

Best Python code snippet using Airtest Github


Full Screen

...626 """627 out =["ls", "-l", filepath])628 file_size = int(out.split()[3])629 return file_size630 def _cleanup_forwards(self):631 """632 Remove the local forward ports633 Returns:634 None635 """636 for local in self._forward_local_using:637 self.start_cmd(["forward", "--remove", local])638 self._forward_local_using = []639 @property640 def line_breaker(self):641 """642 Set carriage return and line break property for various platforms and SDK versions643 Returns:644 carriage return and line break string645 """646 if not self._line_breaker:647 if self.sdk_version >= SDK_VERISON_NEW:648 line_breaker = os.linesep649 else:650 line_breaker = '\r' + os.linesep651 self._line_breaker = line_breaker.encode("ascii")652 return self._line_breaker653 @property654 def display_info(self):655 """656 Set device display properties (orientation, rotation and max values for x and y coordinates)657 Notes:658 if there is a lock screen detected, the function tries to unlock the device first659 Returns:660 device screen properties661 """662 self._display_info_lock.acquire()663 if not self._display_info:664 self._display_info = self.get_display_info()665 self._display_info_lock.release()666 return self._display_info667 def get_display_info(self):668 """669 Get information about device physical display (orientation, rotation and max values for x and y coordinates)670 Returns:671 device screen properties672 """673 display_info = self.getPhysicalDisplayInfo()674 orientation = self.getDisplayOrientation()675 max_x, max_y = self.getMaxXY()676 display_info.update({677 "orientation": orientation,678 "rotation": orientation * 90,679 "max_x": max_x,680 "max_y": max_y,681 })682 return display_info683 def getMaxXY(self):684 """685 Get device display maximum values for x and y coordinates686 Returns:687 max x and max y coordinates688 """689 ret ='getevent -p').split('\n')690 max_x, max_y = None, None691 for i in ret:692 if i.find("0035") != -1:693 patten = re.compile(r'max [0-9]+')694 ret = if ret:696 max_x = int([1])697 if i.find("0036") != -1:698 patten = re.compile(r'max [0-9]+')699 ret = if ret:701 max_y = int([1])702 return max_x, max_y703 def getRestrictedScreen(self):704 """705 Get value for mRestrictedScreen (without black border / virtual keyboard)`706 Returns:707 screen resolution mRestrictedScreen value as tuple (x, y)708 """709 # get the effective screen resolution of the device710 result = None711 # get the corresponding mRestrictedScreen parameters according to the device serial number712 dumpsys_info ="dumpsys window")713 match ='mRestrictedScreen=.+', dumpsys_info)714 if match:715 infoline = # like 'mRestrictedScreen=(0,0) 720x1184'716 resolution = infoline.split(" ")[1].split("x")717 if isinstance(resolution, list) and len(resolution) == 2:718 result = int(str(resolution[0])), int(str(resolution[1]))719 return result720 def getPhysicalDisplayInfo(self):721 """722 Get value for display dimension and density from `mPhysicalDisplayInfo` value obtained from `dumpsys` command.723 Returns:724 physical display info for dimension and density725 """726 phyDispRE = re.compile('.*PhysicalDisplayInfo{(?P<width>\d+) x (?P<height>\d+), .*, density (?P<density>[\d.]+).*')727 out = self.raw_shell('dumpsys display')728 m = if m:730 displayInfo = {}731 for prop in ['width', 'height']:732 displayInfo[prop] = int( for prop in ['density']:734 # In mPhysicalDisplayInfo density is already a factor, no need to calculate735 displayInfo[prop] = float( return displayInfo737 # This could also be mSystem or mOverscanScreen738 phyDispRE = re.compile('\s*mUnrestrictedScreen=\((?P<x>\d+),(?P<y>\d+)\) (?P<width>\d+)x(?P<height>\d+)')739 # This is known to work on older versions (i.e. API 10) where mrestrictedScreen is not available740 dispWHRE = re.compile('\s*DisplayWidth=(?P<width>\d+) *DisplayHeight=(?P<height>\d+)')741 out = self.raw_shell('dumpsys window')742 m =, 0)743 if not m:744 m =, 0)745 if m:746 displayInfo = {}747 for prop in ['width', 'height']:748 displayInfo[prop] = int( for prop in ['density']:750 d = self._getDisplayDensity(None, strip=True)751 if d:752 displayInfo[prop] = d753 else:754 # No available density information755 displayInfo[prop] = -1.0756 return displayInfo757 # gets C{mPhysicalDisplayInfo} values from dumpsys. This is a method to obtain display dimensions and density758 phyDispRE = re.compile('Physical size: (?P<width>\d+)x(?P<height>\d+).*Physical density: (?P<density>\d+)', re.S)759 m ='wm size; wm density'))760 if m:761 displayInfo = {}762 for prop in ['width', 'height']:763 displayInfo[prop] = int( for prop in ['density']:765 displayInfo[prop] = float( return displayInfo767 return {}768 def _getDisplayDensity(self, key, strip=True):769 """770 Get display density771 Args:772 key:773 strip: strip the output774 Returns:775 display density776 """777 BASE_DPI = 160.0778 d = self.getprop('ro.sf.lcd_density', strip)779 if d:780 return float(d) / BASE_DPI781 d = self.getprop('qemu.sf.lcd_density', strip)782 if d:783 return float(d) / BASE_DPI784 return -1.0785 def getDisplayOrientation(self):786 """787 Another way to get the display orientation, this works well for older devices (SDK version 15)788 Returns:789 display orientation information790 """791 # another way to get orientation, for old sumsung device(sdk version 15) from xiaoma792 SurfaceFlingerRE = re.compile('orientation=(\d+)')793 output ='dumpsys SurfaceFlinger')794 m = if m:796 return int( # Fallback method to obtain the orientation798 # See surfaceOrientationRE = re.compile('SurfaceOrientation:\s+(\d+)')800 output ='dumpsys input')801 m = if m:803 return int( # We couldn't obtain the orientation805 warnings.warn("Could not obtain the orientation, return 0")806 return 0807 def get_top_activity(self):808 """809 Perform `adb shell dumpsys activity top` command search for the top activity810 Raises:811 AirtestError: if top activity cannot be obtained812 Returns:813 top activity as a tuple: (package_name, activity_name, pid)814 """815 dat ='dumpsys activity top')816 activityRE = re.compile('\s*ACTIVITY ([A-Za-z0-9_.]+)/([A-Za-z0-9_.]+) \w+ pid=(\d+)')817 # in Android8.0 or higher, the result may be more than one818 m = activityRE.findall(dat)819 if m:820 return m[-1]821 else:822 raise AirtestError("Can not get top activity, output:%s" % dat)823 def is_keyboard_shown(self):824 """825 Perform `adb shell dumpsys input_method` command and search for information if keyboard is shown826 Returns:827 True or False whether the keyboard is shown or not828 """829 dim ='dumpsys input_method')830 if dim:831 return "mInputShown=true" in dim832 return False833 def is_screenon(self):834 """835 Perform `adb shell dumpsys window policy` command and search for information if screen is turned on or off836 Raises:837 AirtestError: if screen state can't be detected838 Returns:839 True or False whether the screen is turned on or off840 """841 screenOnRE = re.compile('mScreenOnFully=(true|false)')842 m ='dumpsys window policy'))843 if m:844 return ( == 'true')845 raise AirtestError("Couldn't determine screen ON state")846 def is_locked(self):847 """848 Perform `adb shell dumpsys window policy` command and search for information if screen is locked or not849 Raises:850 AirtestError: if lock screen can't be detected851 Returns:852 True or False whether the screen is locked or not853 """854 lockScreenRE = re.compile('(?:mShowingLockscreen|isStatusBarKeyguard)=(true|false)')855 m ='dumpsys window policy'))856 if not m:857 raise AirtestError("Couldn't determine screen lock state")858 return ( == 'true')859 def unlock(self):860 """861 Perform `adb shell input keyevent MENU` and `adb shell input keyevent BACK` commands to attempt862 to unlock the screen863 Returns:864 None865 Warnings:866 Might not work on all devices867 """868'input keyevent MENU')869'input keyevent BACK')870 def get_package_version(self, package):871 """872 Perform `adb shell dumpsys package` and search for information about given package version873 Args:874 package: package name875 Returns:876 None if no info has been found, otherwise package version877 """878 package_info =['dumpsys', 'package', package])879 matcher ='versionCode=(\d+)', package_info)880 if matcher:881 return int( return None883 def list_app(self, third_only=False):884 """885 Perform `adb shell pm list packages` to print all packages, optionally only886 those whose package name contains the text in FILTER.887 Options888 -f: see their associated file889 -d: filter to only show disabled packages890 -e: filter to only show enabled packages891 -s: filter to only show system packages892 -3: filter to only show third party packages893 -i: see the installer for the packages894 -u: also include uninstalled packages895 Args:896 third_only: print only third party packages897 Returns:898 list of packages899 """900 cmd = ["pm", "list", "packages"]901 if third_only:902 cmd.append("-3")903 output = packages = output.splitlines()905 # remove all empty string; "package:xxx" -> "xxx"906 packages = [p.split(":")[1] for p in packages if p]907 return packages908 def path_app(self, package):909 """910 Perform `adb shell pm path` command to print the path to the package911 Args:912 package: package name913 Raises:914 AdbShellError: if any adb error occurs915 AirtestError: if package is not found on the device916 Returns:917 path to the package918 """919 try:920 output =['pm', 'path', package])921 except AdbShellError:922 output = ""923 if 'package:' not in output:924 raise AirtestError('package not found, output:[%s]' % output)925 return output.split("package:")[1].strip()926 def check_app(self, package):927 """928 Perform `adb shell dumpsys package` command and check if package exists on the device929 Args:930 package: package name931 Raises:932 AirtestError: if package is not found933 Returns:934 True if package has been found935 """936 output =['dumpsys', 'package', package])937 pattern = r'Package\s+\[' + str(package) + '\]'938 match =, output)939 if match is None:940 raise AirtestError('package "{}" not found'.format(package))941 return True942 def start_app(self, package, activity=None):943 """944 Perform `adb shell monkey` commands to start the application, if `activity` argument is `None`, then945 `adb shell am start` command is used.946 Args:947 package: package name948 activity: activity name949 Returns:950 None951 """952 if not activity:953['monkey', '-p', package, '-c', 'android.intent.category.LAUNCHER', '1'])954 else:955['am', 'start', '-n', '%s/%s.%s' % (package, package, activity)])956 def start_app_timing(self, package, activity):957 """958 Start the application and activity, and measure time959 Args:960 package: package name961 activity: activity name962 Returns:963 app launch time964 """965 out =['am', 'start', '-S', '-W', '%s/%s' % (package, activity),966 '-c', 'android.intent.category.LAUNCHER', '-a', 'android.intent.action.MAIN'])967 if not"Status:\s*ok", out):968 raise AirtestError("Starting App: %s/%s Failed!" % (package, activity))969 matcher ="ThisTime:\s*(\d+)", out)970 if matcher:971 return int( else:973 return 0974 def stop_app(self, package):975 """976 Perform `adb shell am force-stop` command to force stop the application977 Args:978 package: package name979 Returns:980 None981 """982['am', 'force-stop', package])983 def clear_app(self, package):984 """985 Perform `adb shell pm clear` command to clear all application data986 Args:987 package: package name988 Returns:989 None990 """991['pm', 'clear', package])992 def get_ip_address(self):993 """994 Perform several set of commands to obtain the IP address995 * `adb shell netcfg | grep wlan0`996 * `adb shell ifconfig`997 * `adb getprop dhcp.wlan0.ipaddress`998 Returns:999 None if no IP address has been found, otherwise return the IP address1000 """1001 def get_ip_address_from_interface(interface):1002 try:1003 res ='netcfg')1004 except AdbShellError:1005 res = ''1006 matcher = + r'.* ((\d+\.){3}\d+)/\d+', res)1007 if matcher:1008 return else:1010 try:1011 res ='ifconfig')1012 except AdbShellError:1013 res = ''1014 matcher = + r'.*?inet addr:((\d+\.){3}\d+)', res, re.DOTALL)1015 if matcher:1016 return else:1018 try:1019 res ='getprop dhcp.{}.ipaddress'.format(interface))1020 except AdbShellError:1021 res = ''1022 matcher = if matcher:1024 return return None1026 interfaces = ('eth0', 'eth1', 'wlan0')1027 for i in interfaces:1028 ip = get_ip_address_from_interface(i)1029 if ip and not ip.startswith('172.') and not ip.startswith('127.') and not ip.startswith('169.'):1030 return ip1031 return None1032 def get_gateway_address(self):1033 """1034 Perform several set of commands to obtain the gateway address1035 * `adb getprop dhcp.wlan0.gateway`1036 * `adb shell netcfg | grep wlan0`1037 Returns:1038 None if no gateway address has been found, otherwise return the gateway address1039 """1040 ip2int = lambda ip: reduce(lambda a, b: (a << 8) + b, map(int, ip.split('.')), 0)1041 int2ip = lambda n: '.'.join([str(n >> (i << 3) & 0xFF) for i in range(0, 4)[::-1]])1042 try:1043 res ='getprop dhcp.wlan0.gateway')1044 except AdbShellError:1045 res = ''1046 matcher = if matcher:1048 return ip = self.get_ip_address()1050 if not ip:1051 return None1052 mask_len = self._get_subnet_mask_len()1053 gateway = (ip2int(ip) & (((1 << mask_len) - 1) << (32 - mask_len))) + 11054 return int2ip(gateway)1055 def _get_subnet_mask_len(self):1056 """1057 Perform `adb shell netcfg | grep wlan0` command to obtain mask length1058 Returns:1059 17 if mask length could not be detected, otherwise the mask length1060 """1061 try:1062 res ='netcfg')1063 except AdbShellError:1064 pass1065 else:1066 matcher ='wlan0.* (\d+\.){3}\d+/(\d+) ', res)1067 if matcher:1068 return int( # 获取不到网段长度就默认取171070 print('[iputils WARNING] fail to get subnet mask len. use 17 as default.')1071 return 171072 def get_memory(self):1073 res ="dumpsys meminfo")1074 pat = re.compile(r".*Total RAM:\s+(\S+)\s+", re.DOTALL)1075 _str = pat.match(res).group(1)1076 if ',' in _str:1077 _list = _str.split(',')1078 _num = int(_list[0])1079 _num = round(_num + (float(_list[1]) / 1000.0))1080 else:1081 _num = round(float(_str) / 1000.0 / 1000.0)1082 res = str(_num) + 'G'1083 return res1084 def get_storage(self):1085 res ="df /data")1086 pat = re.compile(r".*\/data\s+(\S+)", re.DOTALL)1087 if pat.match(res):1088 _str = pat.match(res).group(1)1089 else:1090 pat = re.compile(r".*\s+(\S+)\s+\S+\s+\S+\s+\S+\s+\/data", re.DOTALL)1091 _str = pat.match(res).group(1)1092 if 'G' in _str:1093 _num = round(float(_str[:-1]))1094 elif 'M' in _str:1095 _num = round(float(_str[:-1]) / 1000.0)1096 else:1097 _num = round(float(_str) / 1000.0 / 1000.0)1098 if _num > 64:1099 res = '128G'1100 elif _num > 32:1101 res = '64G'1102 elif _num > 16:1103 res = '32G'1104 elif _num > 8:1105 res = '16G'1106 else:1107 res = '8G'1108 return res1109 def get_cpuinfo(self):1110 res ="cat /proc/cpuinfo").strip()1111 cpuNum = res.count("processor")1112 pat = re.compile(r'Hardware\s+:\s+(\w+.*)')1113 m = pat.match(res)1114 if not m:1115 pat = re.compile(r'Processor\s+:\s+(\w+.*)')1116 m = pat.match(res)1117 cpuName ='\r', '')1118 return dict(cpuNum=cpuNum, cpuName=cpuName)1119 def get_cpufreq(self):1120 res ="cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq")1121 num = round(float(res) / 1000 / 1000, 1)1122 res = str(num) + 'GHz'1123 return res.strip()1124 def get_cpuabi(self):1125 res ="getprop ro.product.cpu.abi")1126 return res.strip()1127 def get_gpu(self):1128 res ="dumpsys SurfaceFlinger")1129 pat = re.compile(r'GLES:\s+(.*)')1130 m = if not m:1132 return None1133 _list =',')1134 gpuModel = ""1135 opengl = ""1136 if len(_list) > 0:1137 gpuModel = _list[1].strip()1138 if len(_list) > 1:1139 m2 ='(\S+\s+\S+\s+\S+).*', _list[2])1140 if m2:1141 opengl = return dict(gpuModel=gpuModel, opengl=opengl)1143 def get_model(self):1144 return self.getprop("ro.product.model")1145 def get_manufacturer(self):1146 return self.getprop("ro.product.manufacturer")1147 def get_device_info(self):1148 """1149 Get android device information, including: memory/storage/display/cpu/gpu/model/manufacturer...1150 Returns:1151 Dict of info1152 """1153 handlers = {1154 "platform": "Android",1155 "serialno": self.serialno,1156 "memory": self.get_memory,1157 "storage": self.get_storage,1158 "display": self.getPhysicalDisplayInfo,1159 "cpuinfo": self.get_cpuinfo,1160 "cpufreq": self.get_cpufreq,1161 "cpuabi": self.get_cpuabi,1162 "sdkversion": self.sdk_version,1163 "gpu": self.get_gpu,1164 "model": self.get_model,1165 "manufacturer": self.get_manufacturer,1166 # "battery": getBatteryCapacity1167 }1168 ret = {}1169 for k, v in handlers.items():1170 if callable(v):1171 try:1172 value = v()1173 except Exception:1174 value = None1175 ret[k] = value1176 else:1177 ret[k] = v1178 return ret1179 def get_display_of_all_screen(self, info):1180 """1181 Perform `adb shell dumpsys window windows` commands to get window display of application.1182 Args:1183 info: device screen properties1184 Returns:1185 None if adb command failed to run, otherwise return device screen properties1186 """1187 output ="dumpsys window windows")1188 windows = output.split("Window #")1189 offsetx, offsety, x, y = info['width'], info['height'], 0, 01190 package = self._search_for_current_package(output)1191 for w in windows:1192 if "package=%s" % package in w:1193 arr = re.findall(r'Frames: containing=\[(\d+\.?\d*),(\d+\.?\d*)]\[(\d+\.?\d*),(\d+\.?\d*)]', w)1194 if len(arr) >= 1 and len(arr[0]) == 4:1195 offsetx, offsety, x, y = float(arr[0][0]), float(arr[0][1]), float(arr[0][2]), float(arr[0][3])1196 if info["orientation"] in [1, 3]:1197 offsetx, offsety, x, y = offsety, offsetx, y, x1198 x, y = x - offsetx, y - offsety1199 return {1200 "offset_x": offsetx,1201 "offset_y": offsety,1202 "offset_width": x,1203 "offset_height": y1204 }1205 def _search_for_current_package(self, ret):1206 """1207 Search for current app package name from the output of command "adb shell dumpsys window windows"1208 Returns:1209 package name if exists else ""1210 """1211 packageRE = re.compile('\s*mCurrentFocus=Window{.* ([A-Za-z0-9_.]+)/[A-Za-z0-9_.]+}')1212 m = packageRE.findall(ret)1213 if m:1214 return m[-1]1215 return ""1216def cleanup_adb_forward():1217 for adb in ADB._instances:1218 adb._cleanup_forwards()...

Full Screen

Full Screen Github


Full Screen

...114 # set a remote and remove it115 self.adb.forward(local='tcp:6100', remote="tcp:7100")116 self.adb.remove_forward(local='tcp:6100')117 self.assertEqual(len(list(self.adb.get_forwards())), 0)118 def test_cleanup_forwards(self):119 """120 Test that all forward ports have been removed121 测试所有forward的端口号都被remove了122 """123 for port in ['tcp:10010', 'tcp:10020', 'tcp:10030']:124 self.adb.forward(port, port)125 self.adb._cleanup_forwards()126 self.assertEqual(len(list(self.adb.get_forwards())), 0)127 def test_logcat(self):128 line_cnt = 0129 for line in self.adb.logcat():130 self.assertIsInstance(line, str)131 line_cnt += 1132 if line_cnt > 3:133 break134 self.assertGreater(line_cnt, 0)135 def test_pm_install(self):136 if PKG in self.adb.list_app():137 self.adb.pm_uninstall(PKG)138 self.adb.pm_install(APK)139 self.assertIn(PKG, self.adb.list_app())...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:


You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Airtest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?