Watch Star Fork

刘欣 / AirtestPythonApache-2.0

加入码云
与超过 300 万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
跨平台的UI自动化测试框架,适用于游戏和App http://airtest.netease.com/
一键复制 编辑 原始数据 按行查看 历史
# -*- coding: utf-8 -*-
"""
This module contains the Airtest Core APIs.
"""
import os
import time
from six.moves.urllib.parse import parse_qsl, urlparse
from airtest.core.cv import Template, loop_find, try_log_screen
from airtest.core.error import TargetNotFoundError
from airtest.core.helper import (G, delay_after_operation, import_device_cls,
logwrap, on_platform, set_logdir, using)
from airtest.core.settings import Settings as ST
"""
Device Setup APIs
"""
def connect_device(uri):
"""
Initialize device with uri and set the device as the current one.
:param uri: an URI where to connect to device, e.g. `android://adbhost:adbport/serialno?param=value&param2=value2`
:return: device instance
:Example:
* ``android:///`` # local adb device using default params
* ``android://adbhost:adbport/1234566?cap_method=javacap&touch_method=adb`` # remote adb device using custom params
* ``windows:///`` # local Windows application
* ``ios:///`` # iOS device
:platforms: Android, iOS, Windows
"""
d = urlparse(uri)
platform = d.scheme
host = d.netloc
uuid = d.path.lstrip("/")
params = dict(parse_qsl(d.query))
if host:
params["host"] = host.split(":")
cls = import_device_cls(platform)
dev = cls(uuid, **params)
G.add_device(dev)
return dev
def device():
"""
Return the current active device.
:return: current device instance
:platforms: Android, iOS, Windows
"""
return G.DEVICE
@on_platform(["Android", "Windows", "IOS"])
def set_current(index):
"""
Set current active device.
:param index: index of initialized device instance
:raise IndexError: raised when device index is out of device list
:return: None
:platforms: Android, iOS, Windows
"""
try:
G.DEVICE = G.DEVICE_LIST[index]
except IndexError:
raise IndexError("device index out of range: %s/%s" % (index, len(G.DEVICE_LIST)))
def auto_setup(filepath):
"""
Auto setup G.BASEDIR and try connect android device if not connected to any device.
"""
if filepath:
dirname = os.path.dirname(filepath)
if dirname not in G.BASEDIR:
G.BASEDIR.append(dirname)
if not device():
try:
connect_device("Android:///")
except IndexError:
pass
"""
Device Operations
"""
@logwrap
@on_platform(["Android"])
def shell(cmd):
"""
Start remote shell in the target device and execute the command
:param cmd: command to be run on device, e.g. "ls /data/local/tmp"
:return: the output of the shell cmd
:platforms: Android
"""
return G.DEVICE.shell(cmd)
@logwrap
@on_platform(["Android", "IOS"])
def start_app(package, activity=None):
"""
Start the target application on device
:param package: name of the package to be started, e.g. "com.netease.my"
:param activity: the activity to start, default is None which means the main activity
:return: None
:platforms: Android, iOS
"""
G.DEVICE.start_app(package, activity)
@logwrap
@on_platform(["Android", "IOS"])
def stop_app(package):
"""
Stop the target application on device
:param package: name of the package to stop, see also `start_app`
:return: None
:platforms: Android, iOS
"""
G.DEVICE.stop_app(package)
@logwrap
@on_platform(["Android", "IOS"])
def clear_app(package):
"""
Clear data of the target application on device
:param package: name of the package, see also `start_app`
:return: None
:platforms: Android, iOS
"""
G.DEVICE.clear_app(package)
@logwrap
@on_platform(["Android", "IOS"])
def install(filepath):
"""
Install application on device
:param filepath: the path to file to be installed on target device
:return: None
:platforms: Android, iOS
"""
return G.DEVICE.install_app(filepath)
@logwrap
@on_platform(["Android", "IOS"])
def uninstall(package):
"""
Uninstall application on device
:param package: name of the package, see also `start_app`
:return: None
:platforms: Android, iOS
"""
return G.DEVICE.uninstall_app(package)
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def snapshot(filename=None, msg=""):
"""
Take the screenshot of the target device and save it to the file.
:param filename: name of the file where to save the screenshot. If the relative path is provided, the default
location is ``ST.LOG_DIR``
:param msg: short description for screenshot, it will be recorded in the report
:return: absolute path of the screenshot
:platforms: Android, iOS, Windows
"""
if not filename:
filename = "%(time)d.jpg" % {'time': time.time() * 1000}
if not os.path.isabs(filename):
logdir = ST.LOG_DIR or "."
filepath = os.path.join(logdir, filename)
else:
filepath = filename
screen = G.DEVICE.snapshot(filepath)
try_log_screen(screen)
return filepath
@logwrap
@on_platform(["Android", "IOS"])
def wake():
"""
Wake up and unlock the target device
:return: None
:platforms: Android, iOS
.. note:: Might not work on some models
"""
G.DEVICE.wake()
@logwrap
@on_platform(["Android", "IOS"])
def home():
"""
Return to the home screen of the target device.
:return: None
:platforms: Android, iOS
"""
G.DEVICE.home()
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def touch(v, **kwargs):
"""
Perform the touch action on the device screen
:param v: target to touch, either a Template instance or absolute coordinates (x, y)
:param kwargs: platform specific `kwargs`, please refer to corresponding docs
:return: None
:platforms: Android, Windows, iOS
"""
if isinstance(v, Template):
try:
pos = loop_find(v, timeout=ST.FIND_TIMEOUT)
except TargetNotFoundError:
raise
else:
try_log_screen()
pos = v
G.DEVICE.touch(pos, **kwargs)
delay_after_operation()
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def swipe(v1, v2=None, vector=None, **kwargs):
"""
Perform the swipe action on the device screen.
There are two ways of assigning the parameters
* ``swipe(v1, v2=Template(...))`` # swipe from v1 to v2
* ``swipe(v1, vector=(x, y))`` # swipe starts at v1 and moves along the vector.
:param v1: the start point of swipe,
either a Template instance or absolute coordinates (x, y)
:param v2: the end point of swipe,
either a Template instance or absolute coordinates (x, y)
:param vector: a vector coordinates of swipe action, either absolute coordinates (x, y) or percentage of
screen e.g.(0.5, 0.5)
:param **kwargs: platform specific `kwargs`, please refer to corresponding docs
:raise Exception: general exception when not enough parameters to perform swap action have been provided
:return: None
:platforms: Android, Windows, iOS
"""
if isinstance(v1, Template):
pos1 = loop_find(v1, timeout=ST.FIND_TIMEOUT)
else:
try_log_screen()
pos1 = v1
if v2:
if isinstance(v2, Template):
pos2 = loop_find(v2, timeout=ST.FIND_TIMEOUT_TMP)
else:
pos2 = v2
elif vector:
if vector[0] <= 1 and vector[1] <= 1:
w, h = G.DEVICE.get_current_resolution()
vector = (int(vector[0] * w), int(vector[1] * h))
pos2 = (pos1[0] + vector[0], pos1[1] + vector[1])
else:
raise Exception("no enough params for swipe")
G.DEVICE.swipe(pos1, pos2, **kwargs)
delay_after_operation()
@logwrap
@on_platform(["Android"])
def pinch(in_or_out='in', center=None, percent=0.5):
"""
Perform the pinch action on the device screen
:param in_or_out: pinch in or pinch out, enum in ["in", "out"]
:param center: center of pinch action, default as None which is the center of the screen
:param percent: percentage of the screen of pinch action, default is 0.5
:return: None
:platforms: Android
"""
G.DEVICE.pinch(in_or_out=in_or_out, center=center, percent=percent)
delay_after_operation()
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def keyevent(keyname, **kwargs):
"""
Perform key event on the device
:param keyname: platform specific key name
:param **kwargs: platform specific `kwargs`, please refer to corresponding docs
:return: None
:platforms: Android, Windows, iOS
"""
G.DEVICE.keyevent(keyname, **kwargs)
delay_after_operation()
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def text(text, enter=True):
"""
Input text on the target device. Text input widget must be active first.
:param text: text to input, unicode is supported
:param enter: input `Enter` keyevent after text input, default is True
:return: None
:platforms: Android, Windows, iOS
"""
G.DEVICE.text(text, enter=enter)
delay_after_operation()
@logwrap
def sleep(secs=1.0):
"""
Set the sleep interval. It will be recorded in the report
:param secs: seconds to sleep
:return: None
:platforms: Android, Windows, iOS
"""
time.sleep(secs)
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def wait(v, timeout=None, interval=0.5, intervalfunc=None):
"""
Wait to match the Template on the device screen
:param v: target object to wait for, Template instance
:param timeout: time interval to wait for the match, default is None which is ``ST.FIND_TIMEOUT``
:param interval: time interval in seconds to attempt to find a match
:param intervalfunc: called after each unsuccessful attempt to find the corresponding match
:raise TargetNotFoundError: raised if target is not found after the time limit expired
:return: coordinates of the matched target
:platforms: Android, Windows, iOS
"""
timeout = timeout or ST.FIND_TIMEOUT
pos = loop_find(v, timeout=timeout, interval=interval, intervalfunc=intervalfunc)
return pos
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def exists(v):
"""
Check whether given target exists on device screen
:param v: target to be checked
:return: False if target is not found, otherwise returns the coordinates of the target
:platforms: Android, Windows, iOS
"""
try:
pos = loop_find(v, timeout=ST.FIND_TIMEOUT_TMP)
except TargetNotFoundError:
return False
else:
return pos
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def find_all(v):
"""
Find all occurrences of the target on the device screen and return their coordinates
:param v: target to find
:return: list of coordinates, [(x, y), (x1, y1), ...]
:platforms: Android, Windows, iOS
"""
screen = G.DEVICE.snapshot()
return v.match_all_in(screen)
"""
Assertions
"""
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def assert_exists(v, msg=""):
"""
Assert target exists on device screen
:param v: target to be checked
:param msg: short description of assertion, it will be recorded in the report
:raise AssertionError: if assertion fails
:return: coordinates of the target
:platforms: Android, Windows, iOS
"""
try:
pos = loop_find(v, timeout=ST.FIND_TIMEOUT, threshold=ST.THRESHOLD_STRICT)
return pos
except TargetNotFoundError:
raise AssertionError("%s does not exist in screen, message: %s" % (v, msg))
@logwrap
@on_platform(["Android", "Windows", "IOS"])
def assert_not_exists(v, msg=""):
"""
Assert target does not exist on device screen
:param v: target to be checked
:param msg: short description of assertion, it will be recorded in the report
:raise AssertionError: if assertion fails
:return: None.
:platforms: Android, Windows, iOS
"""
try:
pos = loop_find(v, timeout=ST.FIND_TIMEOUT_TMP)
raise AssertionError("%s exists unexpectedly at pos: %s, message: %s" % (v, pos, msg))
except TargetNotFoundError:
pass
@logwrap
def assert_equal(first, second, msg=""):
"""
Assert two values are equal
:param first: first value
:param second: second value
:param msg: short description of assertion, it will be recorded in the report
:raise AssertionError: if assertion fails
:return: None
:platforms: Android, Windows, iOS
"""
if first != second:
raise AssertionError("%s and %s are not equal, message: %s" % (first, second, msg))
@logwrap
def assert_not_equal(first, second, msg=""):
"""
Assert two values are not equal
:param first: first value
:param second: second value
:param msg: short description of assertion, it will be recorded in the report
:raise AssertionError: if assertion
:return: None
:platforms: Android, Windows, iOS
"""
if first == second:
raise AssertionError("%s and %s are equal, message: %s" % (first, second, msg))

评论 ( 0 )

你可以在登录后,发表评论

搜索帮助