Skip to content

Commit

Permalink
Merge pull request #1186 from AirtestProject/v1.3.3
Browse files Browse the repository at this point in the history
V1.3.3
  • Loading branch information
yimelia authored Jan 8, 2024
2 parents 1d71c4e + 551b868 commit 35f5024
Show file tree
Hide file tree
Showing 18 changed files with 457 additions and 71 deletions.
22 changes: 22 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.6"

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py

# We recommend specifying your dependencies to enable reproducible builds:
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: docs/requirements.txt
10 changes: 7 additions & 3 deletions airtest/core/android/adb.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,13 @@ def get_adb_path():
ADB_NAME = "adb"

# Check if adb process is already running
for process in psutil.process_iter(['name', 'exe']):
if process.info['name'] == ADB_NAME:
return process.info['exe']
try:
for process in psutil.process_iter(['name', 'exe']):
if process.info['name'] == ADB_NAME and process.info['exe'] and os.path.exists(process.info['exe']):
return process.info['exe']
except:
# maybe OSError
pass

# Check if ANDROID_HOME environment variable exists
android_home = os.environ.get('ANDROID_HOME')
Expand Down
98 changes: 87 additions & 11 deletions airtest/core/android/android.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from airtest.core.settings import Settings as ST
from airtest.aircv.screen_recorder import ScreenRecorder, resize_by_max, get_max_size
from airtest.utils.snippet import get_absolute_coordinate
from airtest.utils.logger import get_logger

LOGGING = get_logger(__name__)
Expand All @@ -45,7 +46,7 @@ def __init__(self, serialno=None, host=None,
adb_path=None,
name=None):
super(Android, self).__init__()
self.serialno = serialno or self.get_default_device()
self.serialno = serialno or self.get_default_device(adb_path=adb_path)
self._uuid = name or self.serialno
self._cap_method = cap_method.upper()
self._touch_method = touch_method.upper()
Expand Down Expand Up @@ -99,6 +100,39 @@ def touch_proxy(self):
input_event=self.input_event)
return self._touch_proxy

@touch_proxy.setter
def touch_proxy(self, touch_method):
"""
Specify a touch method, if the method fails to initialize, try to use other methods instead
指定一个触摸方案,如果该方法初始化失败,则尝试使用其他方法代替
Args:
touch_method: "MINITOUCH" or Minitouch() object
Returns:
TouchProxy object
Raises:
TouchMethodNotSupportedError when the connection fails
Examples:
>>> dev = Android()
>>> dev.touch_proxy = "MINITOUCH"
>>> from airtest.core.android.touch_methods.minitouch import Minitouch
>>> minitouch = Minitouch(dev.adb)
>>> dev.touch_proxy = minitouch
"""
if self._screen_proxy:
self._screen_proxy.teardown()
self._touch_proxy = TouchProxy.auto_setup(self.adb,
default_method=touch_method,
ori_transformer=self._touch_point_by_orientation,
size_info=self.display_info,
input_event=self.input_event)

@property
def touch_method(self):
"""
Expand All @@ -116,6 +150,29 @@ def touch_method(self):
"""
return self.touch_proxy.method_name

@touch_method.setter
def touch_method(self, name):
"""
Specify the touch method for the device, but this is not recommended
为设备指定触摸方案,但不建议这样做
Just to be compatible with some old codes
仅为了兼容一些旧的代码
Args:
name: "MINITOUCH" or Minitouch() object
Returns:
None
Examples:
>>> dev = Android()
>>> dev.touch_method = "MINITOUCH"
"""
warnings.warn("No need to manually specify touch_method, airtest will automatically specify a suitable touch method, when airtest>=1.1.2")
self.touch_proxy = name

@property
def cap_method(self):
"""
Expand Down Expand Up @@ -532,16 +589,25 @@ def touch(self, pos, duration=0.01):
pos: coordinates (x, y)
duration: how long to touch the screen
Examples:
>>> dev = Android() # or dev = device()
>>> dev.touch((100, 100)) # absolute coordinates
>>> dev.touch((0.5, 0.5)) # relative coordinates
Returns:
None
(x, y) # The coordinate position of the actual click
"""
pos = get_absolute_coordinate(pos, self)
self.touch_proxy.touch(pos, duration)
return pos

def double_click(self, pos):
pos = get_absolute_coordinate(pos, self)
self.touch(pos)
time.sleep(0.05)
self.touch(pos)
return pos

def swipe(self, p1, p2, duration=0.5, steps=5, fingers=1):
"""
Expand All @@ -554,11 +620,19 @@ def swipe(self, p1, p2, duration=0.5, steps=5, fingers=1):
steps: how big is the swipe step, default 5
fingers: the number of fingers. 1 or 2.
Examples:
>>> dev = Android() # or dev = device()
>>> dev.swipe((100, 100), (200, 200)) # absolute coordinates
>>> dev.swipe((0.1, 0.1), (0.2, 0.2)) # relative coordinates
Returns:
None
(pos1, pos2)
"""
p1 = get_absolute_coordinate(p1, self)
p2 = get_absolute_coordinate(p2, self)
self.touch_proxy.swipe(p1, p2, duration=duration, steps=steps, fingers=fingers)
return p1, p2

def pinch(self, center=None, percent=0.5, duration=0.5, steps=5, in_or_out='in'):
"""
Expand Down Expand Up @@ -593,6 +667,7 @@ def swipe_along(self, coordinates_list, duration=0.8, steps=5):
None
"""
coordinates_list = [get_absolute_coordinate(pos, self) for pos in coordinates_list]
self.touch_proxy.swipe_along(coordinates_list, duration=duration, steps=steps)

def two_finger_swipe(self, tuple_from_xy, tuple_to_xy, duration=0.8, steps=5, offset=(0, 50)):
Expand All @@ -609,6 +684,8 @@ def two_finger_swipe(self, tuple_from_xy, tuple_to_xy, duration=0.8, steps=5, of
Returns:
None
"""
tuple_from_xy = get_absolute_coordinate(tuple_from_xy, self)
tuple_to_xy = get_absolute_coordinate(tuple_to_xy, self)
self.touch_proxy.two_finger_swipe(tuple_from_xy, tuple_to_xy, duration=duration, steps=steps, offset=offset)

def logcat(self, *args, **kwargs):
Expand Down Expand Up @@ -930,6 +1007,13 @@ def get_clipboard(self):
Returns:
clipboard content
Examples:
>>> dev = Android()
>>> dev.set_clipboard("hello world")
>>> dev.get_clipboard()
'hello world'
>>> dev.paste() # paste the clipboard content
"""
return self.yosemite_ext.get_clipboard()

Expand All @@ -946,14 +1030,6 @@ def set_clipboard(self, text):
"""
self.yosemite_ext.set_clipboard(text)

def paste(self):
"""
Paste the clipboard content
Returns:
"""
self.text(self.get_clipboard())

def _register_rotation_watcher(self):
"""
Register callbacks for Android and minicap when rotation of screen has changed
Expand Down
26 changes: 15 additions & 11 deletions airtest/core/android/cap_methods/minicap.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,20 +398,24 @@ def _cleanup_minicap(self):
TASK_INTERRUPTIBLE1 = "__skb_wait_for_more_packets"
TASK_INTERRUPTIBLE2 = "futex_wait_queue_me"

shell_output = ""
try:
shell_output = self.adb.shell("ps -A| grep minicap")
except:
pass
else:
if len(shell_output) == 0:
return
for line in shell_output.split("\r\n"):
if TASK_INTERRUPTIBLE1 in line or TASK_INTERRUPTIBLE2 in line:
pid = line.split()[1]
try:
self.adb.shell("kill %s" % pid)
except:
pass
try:
shell_output = self.adb.shell("ps| grep minicap")
except:
pass

if len(shell_output) == 0:
return
for line in shell_output.split("\r\n"):
if TASK_INTERRUPTIBLE1 in line or TASK_INTERRUPTIBLE2 in line:
pid = line.split()[1]
try:
self.adb.shell("kill %s" % pid)
except:
pass

def _cleanup(self):
"""
Expand Down
24 changes: 24 additions & 0 deletions airtest/core/android/ime.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# coding=utf-8
import re
from airtest.core.android.yosemite import Yosemite
from .constant import YOSEMITE_PACKAGE
from airtest.core.error import AdbError
from airtest.utils.snippet import escape_special_char
from .constant import YOSEMITE_IME_SERVICE
from six import text_type
import requests
import time


def ensure_unicode(value):
Expand Down Expand Up @@ -122,6 +125,27 @@ def text(self, value):
"""
if not self.started:
self.start()
installed_version = self.adb.get_package_version(YOSEMITE_PACKAGE)
if installed_version is not None and int(installed_version) >= int(430):
local_port = self.adb.get_available_forward_local()
self.adb.forward(local=f'tcp:{local_port}', remote="tcp:8181", no_rebind=False)
for i in range(15):
try:
url = f'http://{self.adb.host}:{local_port}/ime_onStartInput'
ret = requests.get(url, timeout=3)
except Exception as e:
time.sleep(1)
if i % 3 == 0: # 超时未启动,再尝试启动
print(f"Trying to initialize input method again.")
self.start()
else:
if 'ime_onStartInput=ok' in ret.text:
self.adb.remove_forward(local=f'tcp:{local_port}')
break
else:
self.adb.remove_forward(local=f'tcp:{local_port}')
raise AdbError("IME Error", "IME initialization timed out.")

# 更多的输入用法请见 https://github.com/macacajs/android-unicode#use-in-adb-shell
value = ensure_unicode(value)
value = escape_special_char(value)
Expand Down
Binary file modified airtest/core/android/static/apks/Yosemite.apk
Binary file not shown.
22 changes: 16 additions & 6 deletions airtest/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ def touch(v, times=1, **kwargs):
>>> touch(Template(r"tpl1606730579419.png", target_pos=5))
Click on relative coordinates, for example, click on the center of the screen::
>>> touch((0.5, 0.5))
Click 2 times::
>>> touch((100, 100), times=2)
Expand All @@ -364,7 +368,9 @@ def touch(v, times=1, **kwargs):
try_log_screen()
pos = v
for _ in range(times):
G.DEVICE.touch(pos, **kwargs)
# If pos is a relative coordinate, return the converted click coordinates.
# iOS may all use vertical screen coordinates, so coordinates will not be returned.
pos = G.DEVICE.touch(pos, **kwargs) or pos
time.sleep(0.05)
delay_after_operation()
return pos
Expand All @@ -389,7 +395,7 @@ def double_click(v):
else:
try_log_screen()
pos = v
G.DEVICE.double_click(pos)
pos = G.DEVICE.double_click(pos) or pos
delay_after_operation()
return pos

Expand Down Expand Up @@ -424,6 +430,10 @@ def swipe(v1, v2=None, vector=None, **kwargs):
>>> # swiping lasts for 1 second, divided into 6 steps
>>> swipe((100, 100), (200, 200), duration=1, steps=6)
Use relative coordinates to swipe, such as swiping from the center right to the left of the screen::
>>> swipe((0.7, 0.5), (0.2, 0.5))
"""
if isinstance(v1, Template):
try:
Expand All @@ -450,7 +460,7 @@ def swipe(v1, v2=None, vector=None, **kwargs):
else:
raise Exception("no enough params for swipe")

G.DEVICE.swipe(pos1, pos2, **kwargs)
pos1, pos2 = G.DEVICE.swipe(pos1, pos2, **kwargs) or (pos1, pos2)
delay_after_operation()
return pos1, pos2

Expand Down Expand Up @@ -664,7 +674,7 @@ def get_clipboard(*args, **kwargs):
Get the content from the clipboard.
:return: str
:platforms: Android, iOS
:platforms: Android, iOS, Windows
:Example:
>>> text = get_clipboard() # Android or local iOS
Expand All @@ -685,7 +695,7 @@ def set_clipboard(content, *args, **kwargs):
:param content: str
:return: None
:platforms: Android, iOS
:platforms: Android, iOS, Windows
:Example:
>>> set_clipboard("content") # Android or local iOS
Expand All @@ -703,7 +713,7 @@ def paste(*args, **kwargs):
"""
Paste the content from the clipboard.
:platforms: Android, iOS
:platforms: Android, iOS, Windows
:return: None
:Example:
Expand Down
9 changes: 9 additions & 0 deletions airtest/core/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ def get_render_resolution(self):
def get_ip_address(self):
self._raise_not_implemented_error()

def set_clipboard(self, text):
self._raise_not_implemented_error()

def get_clipboard(self):
self._raise_not_implemented_error()

def paste(self):
self.text(self.get_clipboard())

def _raise_not_implemented_error(self):
platform = self.__class__.__name__
raise NotImplementedError("Method not implemented on %s" % platform)
Expand Down
Loading

0 comments on commit 35f5024

Please sign in to comment.