Skip to content

Commit

Permalink
Merge pull request #897 from AirtestProject/dev
Browse files Browse the repository at this point in the history
1.1.10-1.1.11更新
  • Loading branch information
yimelia committed Apr 30, 2021
2 parents 0626844 + f42c30e commit db2fb92
Show file tree
Hide file tree
Showing 23 changed files with 72 additions and 36 deletions.
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ include airtest/core/android/static/*/*/*
include airtest/core/android/static/*/*
include airtest/core/android/static/stf_libs/minicap-shared/aosp/libs/*/*/*.*

include airtest/core/ios/iproxy/*/*

include airtest/report/*.html
include airtest/report/*/*.*
include airtest/report/*/*/*.*
25 changes: 15 additions & 10 deletions airtest/core/android/adb.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from airtest.utils.logger import get_logger
from airtest.utils.nbsp import NonBlockingStreamReader
from airtest.utils.retry import retries
from airtest.utils.snippet import get_std_encoding, reg_cleanup, split_cmd
from airtest.utils.snippet import get_std_encoding, reg_cleanup, split_cmd, make_file_executable

LOGGING = get_logger(__name__)

Expand Down Expand Up @@ -67,6 +67,9 @@ def builtin_adb_path():
# overwrite uiautomator adb
if "ANDROID_HOME" in os.environ:
del os.environ["ANDROID_HOME"]
if system != "Windows":
# chmod +x adb
make_file_executable(adb_path)
return adb_path

def _set_cmd_options(self, server_addr=None):
Expand Down Expand Up @@ -509,13 +512,14 @@ def get_available_forward_local(cls):
return random.randint(11111, 20000)

@retries(3)
def setup_forward(self, device_port):
def setup_forward(self, device_port, no_rebind=True):
"""
Generate pseudo random local port and check if the port is available.
Args:
device_port: it can be string or the value of the `function(localport)`,
e.g. `"tcp:5001"` or `"localabstract:{}".format`
no_rebind: adb forward --no-rebind option
Returns:
local port and device port
Expand All @@ -524,7 +528,7 @@ def setup_forward(self, device_port):
localport = self.get_available_forward_local()
if callable(device_port):
device_port = device_port(localport)
self.forward("tcp:%s" % localport, device_port)
self.forward("tcp:%s" % localport, device_port, no_rebind=no_rebind)
return localport, device_port

def remove_forward(self, local=None):
Expand Down Expand Up @@ -1507,27 +1511,28 @@ def get_display_of_all_screen(self, info):
info: device screen properties
Returns:
None if adb command failed to run, otherwise return device screen properties
None if adb command failed to run, otherwise return device screen properties(portrait mode)
eg. (offset_x, offset_y, screen_width, screen_height)
"""
output = self.shell("dumpsys window windows")
windows = output.split("Window #")
offsetx, offsety, x, y = info['width'], info['height'], 0, 0
offsetx, offsety, width, height = 0, 0, info['width'], info['height']
package = self._search_for_current_package(output)
if package:
for w in windows:
if "package=%s" % package in w:
arr = re.findall(r'Frames: containing=\[(\d+\.?\d*),(\d+\.?\d*)]\[(\d+\.?\d*),(\d+\.?\d*)]', w)
if len(arr) >= 1 and len(arr[0]) == 4:
offsetx, offsety, x, y = float(arr[0][0]), float(arr[0][1]), float(arr[0][2]), float(arr[0][3])
offsetx, offsety, width, height = float(arr[0][0]), float(arr[0][1]), float(arr[0][2]), float(arr[0][3])
if info["orientation"] in [1, 3]:
offsetx, offsety, x, y = offsety, offsetx, y, x
x, y = x - offsetx, y - offsety
offsetx, offsety, width, height = offsety, offsetx, height, width
width, height = width - offsetx, height - offsety
return {
"offset_x": offsetx,
"offset_y": offsety,
"offset_width": x,
"offset_height": y
"offset_width": width,
"offset_height": height,
}

def _search_for_current_package(self, ret):
Expand Down
2 changes: 1 addition & 1 deletion airtest/core/android/android.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ def wake(self):
self.recorder.install_or_upgrade() # 暂时Yosemite只用了ime
self.adb.shell(['am', 'start', '-a', 'com.netease.nie.yosemite.ACTION_IDENTIFY'])
time.sleep(0.5)
self.keyevent("HOME")
self.home()

def home(self):
"""
Expand Down
Binary file modified airtest/core/android/static/apks/rotationwatcher.jar
Binary file not shown.
6 changes: 4 additions & 2 deletions airtest/core/ios/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@


THISPATH = decode_path(os.path.dirname(os.path.realpath(__file__)))
IPROXY_PATH = os.path.join(THISPATH, "iproxy", "iproxy.exe")
DEFAULT_ADB_SERVER = ('127.0.0.1', 8100)
DEFAULT_IPROXY_PATH = {
"Windows": os.path.join(THISPATH, "iproxy", "windows", "iproxy.exe"),
"Darwin": os.path.join(THISPATH, "iproxy", "mac", "iproxy"),
}
DEBUG = True
IP_PATTERN = re.compile(r'(\d+\.){3}\d+')

Expand Down
39 changes: 22 additions & 17 deletions airtest/core/ios/instruct_cmd.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
import os
import subprocess
import time
import sys
Expand All @@ -10,12 +9,12 @@
import threading
import wda
from airtest.core.error import AirtestError
from airtest.utils.snippet import reg_cleanup, on_method_ready, get_std_encoding
from airtest.utils.snippet import reg_cleanup, make_file_executable, get_std_encoding
from airtest.utils.logger import get_logger
from airtest.utils.retry import retries
from airtest.utils.compat import SUBPROCESS_FLAG
from airtest.core.ios.constant import IPROXY_PATH
from airtest.core.ios.relay import ThreadedTCPServer, TCPRelay, select, TCPServer
from airtest.core.ios.constant import DEFAULT_IPROXY_PATH
from airtest.core.ios.relay import ThreadedTCPServer, TCPRelay

LOGGING = get_logger(__name__)

Expand All @@ -38,15 +37,19 @@ def __init__(self, uuid=None):

@staticmethod
def builtin_iproxy_path():
# iOS的端口转发主要分为以下几种情况:
# 1. windows上使用iproxy.exe port1 port2 uid
# 2. mac上如果安装了iproxy,同理,如果没有安装则抛出warning
# 并且使用relay.py中的逻辑用python转发(效率慢)
# Port forwarding for iOS:
# 1. Windows/Mac: iproxy.exe/iproxy -u uid port1 port2
# 2. Ubuntu linux: apt-get install libusbmuxd-tools; iproxy port1 port2
# 3. Use python (low efficiency): python relay.py -t 5100:5100
if shutil.which("iproxy"):
return shutil.which("iproxy")
if platform.system() == "Windows":
return IPROXY_PATH
warnings.warn("Please run the command to install iproxy for a better experience: brew install usbmuxd")
system = platform.system()
iproxy_path = DEFAULT_IPROXY_PATH.get(system)
if iproxy_path:
if system == "Darwin":
make_file_executable(iproxy_path)
return iproxy_path
warnings.warn("Please install iproxy for a better experience(Ubuntu Linux): apt-get install libusbmuxd-tools")
return None

@property
Expand All @@ -60,12 +63,13 @@ def usb_device(self):
if not self._device:
# wda无法直接获取iOS的udid,因此先检查usb连接的手机udid列表
for dev in wda.usbmux.Usbmux().device_list():
usb_dev = wda.Client(url=wda.requests_usbmux.DEFAULT_SCHEME + dev['UDID'])
udid = dev.get('SerialNumber')
usb_dev = wda.Client(url=wda.requests_usbmux.DEFAULT_SCHEME + udid)
# 对比wda.info获取到的uuid是否一致
try:
if usb_dev.info['uuid'] == self.uuid:
self._device = wda.usbmux.Device(dev['UDID'])
self._udid = dev['UDID']
self._device = wda.usbmux.Device(udid)
self._udid = udid
except:
return None
return self._device
Expand Down Expand Up @@ -96,8 +100,12 @@ def do_proxy(self, local_port, device_port):
if proxy_process:
cmds = [proxy_process, "-u", self._udid, str(local_port), str(device_port)]
else:
# Port forwarding using python
self.do_proxy_usbmux(local_port, device_port)
return

# Port forwarding using iproxy
# e.g. cmds=['/usr/local/bin/iproxy', '-u', '00008020-001270842E88002E', '11565', '5001']
proc = subprocess.Popen(
cmds,
stdin=subprocess.PIPE,
Expand All @@ -121,7 +129,6 @@ def do_proxy_usbmux(self, lport, rport):
server.rport = rport
server.device = self.usb_device
server.bufsize = 128
alive = True
self.server = server
self.server_thread = threading.Thread(target=self.server.serve_forever)
self.server_thread.daemon = True
Expand All @@ -130,7 +137,5 @@ def do_proxy_usbmux(self, lport, rport):


if __name__ == '__main__':
# ins = InstructHelper()
# ins.do_proxy(8100, 8100)
ins = InstructHelper()
ins.do_proxy_usbmux(5001, 5001)
4 changes: 2 additions & 2 deletions airtest/core/ios/ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ def get_orientation(self):
# self.driver.orientation只能拿到LANDSCAPE,不能拿到左转/右转的确切方向
# 因此手动调用/rotation获取屏幕实际方向
rotation = self.driver._session_http.get('/rotation')
# rotation eg. AttrDict({'value': {'x': 0, 'y': 0, 'z': 90}, 'sessionId': 'xx', 'status': 0})
# rotation dict eg. {'value': {'x': 0, 'y': 0, 'z': 90}, 'sessionId': 'xx', 'status': 0}
if rotation:
return ROTATION_MODE.get(rotation.value.z, wda.PORTRAIT)
return ROTATION_MODE.get(rotation['value']['z'], wda.PORTRAIT)

@property
def display_info(self):
Expand Down
Binary file removed airtest/core/ios/iproxy/getopt.dll
Binary file not shown.
Binary file removed airtest/core/ios/iproxy/iproxy.exe
Binary file not shown.
Binary file added airtest/core/ios/iproxy/mac/iproxy
Binary file not shown.
Binary file added airtest/core/ios/iproxy/mac/libplist-2.0.dylib
Binary file not shown.
Binary file added airtest/core/ios/iproxy/mac/libusbmuxd.dylib
Binary file not shown.
Binary file removed airtest/core/ios/iproxy/plist.dll
Binary file not shown.
Binary file removed airtest/core/ios/iproxy/usbmuxd.dll
Binary file not shown.
Binary file added airtest/core/ios/iproxy/windows/getopt.dll
Binary file not shown.
Binary file added airtest/core/ios/iproxy/windows/iproxy.exe
Binary file not shown.
Binary file added airtest/core/ios/iproxy/windows/plist.dll
Binary file not shown.
Binary file added airtest/core/ios/iproxy/windows/usbmuxd.dll
Binary file not shown.
4 changes: 3 additions & 1 deletion airtest/core/ios/relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __init__(self, a, b, maxbuf=65535):
self.atob = b""
self.btoa = b""
self.maxbuf = maxbuf

def handle(self):
while True:
rlist = []
Expand Down Expand Up @@ -76,7 +77,8 @@ class TCPServer(SocketServer.TCPServer):


class ThreadedTCPServer(SocketServer.ThreadingMixIn, TCPServer):
pass
# 显式指定为True,否则脚本运行完毕时,因为连接没有断开,导致线程不会终止
daemon_threads = True


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion airtest/utils/nbsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, stream, raise_EOF=False, print_output=True, print_new_line=Tr

def _populateQueue(stream, queue, kill_event):
'''
Collect lines from 'stream' and put them in 'quque'.
Collect lines from 'stream' and put them in 'queue'.
'''
while not kill_event.is_set():
line = stream.readline()
Expand Down
16 changes: 16 additions & 0 deletions airtest/utils/snippet.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# _*_ coding:UTF-8 _*_
import os
import sys
import stat
import threading
from functools import wraps
from six import string_types
Expand Down Expand Up @@ -118,3 +119,18 @@ def wrapper(inst, *args, **kwargs):
setattr(inst, key, True)
return ret
return wrapper


def make_file_executable(file_path):
"""
If the path does not have executable permissions, execute chmod +x
:param file_path:
:return:
"""
if os.path.isfile(file_path):
mode = os.lstat(file_path)[stat.ST_MODE]
executable = True if mode & stat.S_IXUSR else False
if not executable:
os.chmod(file_path, mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
return True
return False
2 changes: 1 addition & 1 deletion airtest/utils/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.1.9"
__version__ = "1.1.11"

import os
import sys
Expand Down
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ def parse_requirements(filename):
# If py<=3.6 and opencv-contrib-python has not been installed, install version==3.2.0.7
reqs.remove("opencv-contrib-python")
reqs.append("opencv-contrib-python==3.2.0.7")
if sys.version_info.major == 2:
# facebook-wda only supports py3
reqs.remove("facebook-wda>=1.3.3")
return reqs


Expand All @@ -48,7 +51,8 @@ def parse_requirements(filename):
packages=find_packages(exclude=['cover', 'playground', 'tests', 'dist']),
package_data={
'android_deps': ["*.apk", "airtest/core/android/static"],
'html_statics': ["airtest/report"]
'html_statics': ["airtest/report"],
'ios_deps': ["airtest/core/ios/iproxy"],
},
include_package_data=True,
install_requires=parse_requirements('requirements.txt'),
Expand Down

0 comments on commit db2fb92

Please sign in to comment.