def snapshot(filename=None, msg="", quality=None, max_size=None): """ 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 :param quality: The image quality, integer in range [1, 99], default is 10 :param max_size: the maximum size of the picture, e.g 1200 :return: absolute path of the screenshot :platforms: Android, iOS, Windows """ if not quality: quality = ST.SNAPSHOT_QUALITY if not max_size and ST.IMAGE_MAXSIZE: max_size = ST.IMAGE_MAXSIZE if filename: if not os.path.isabs(filename): logdir = ST.LOG_DIR or "." filename = os.path.join(logdir, filename) screen = G.DEVICE.snapshot(filename, quality=quality, max_size=max_size) return try_log_screen(screen, quality=quality, max_size=max_size) else: return try_log_screen(quality=quality, max_size=max_size)
def double_click(v): if isinstance(v, Template): pos = loop_find(v, timeout=ST.FIND_TIMEOUT) else: try_log_screen() pos = v G.DEVICE.double_click(pos) delay_after_operation()
def log(arg, timestamp=None, desc="", snapshot=False): """ Insert user log, will be displayed in Html report. Args: arg: log message or Exception object timestamp: the timestamp of the log, default is time.time() desc: description of log, default is arg.class.__name__ snapshot: whether to take a screenshot, default is False Returns: None Examples: >>> log("hello world", snapshot=True) >>> log({"key": "value"}, timestamp=time.time(), desc="log dict") >>> try: 1/0 except Exception as e: log(e) """ from airtest.core.cv import try_log_screen if G.LOGGER: depth = 0 if snapshot: # 如果指定了snapshot参数,强制保存一张图片 save_image = ST.SAVE_IMAGE ST.SAVE_IMAGE = True try: try_log_screen(depth=2) except AttributeError: # if G.DEVICE is None pass else: depth = 1 finally: ST.SAVE_IMAGE = save_image if isinstance(arg, Exception): if hasattr(arg, "__traceback__"): # in PY3, arg.__traceback__ is traceback object trace_msg = ''.join(traceback.format_exception(type(arg), arg, arg.__traceback__)) else: trace_msg = arg.message # PY2 G.LOGGER.log("info", { "name": desc or arg.__class__.__name__, "traceback": trace_msg, }, depth=depth, timestamp=timestamp) G.LOGGING.error(trace_msg) elif isinstance(arg, six.string_types): # 普通文本log内容放在"log"里,如果有trace内容放在"traceback"里 # 在报告中,假如"traceback"有内容,将会被识别为报错,这个步骤会被判定为不通过 G.LOGGER.log("info", {"name": desc or arg, "traceback": None, "log": arg}, depth=depth, timestamp=timestamp) G.LOGGING.info(arg) else: G.LOGGER.log("info", {"name": desc or repr(arg), "traceback": None, "log": repr(arg)}, depth=depth, timestamp=timestamp) G.LOGGING.info(repr(arg))
def hover(v): """ Perform mouse move and stop """ if isinstance(v, Template): pos = loop_find(v, timeout=ST.FIND_TIMEOUT) else: try_log_screen() pos = v G.DEVICE.hover(pos) delay_after_operation() return pos
def right_click(v): """ Perform right click """ if isinstance(v, Template): pos = loop_find(v, timeout=ST.FIND_TIMEOUT) else: try_log_screen() pos = v G.DEVICE.right_click(pos) delay_after_operation() return pos
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: Origin position and target position :platforms: Android, Windows, iOS :Example: >>> swipe(Template(r"tpl1606814865574.png"), vector=[-0.0316, -0.3311]) >>> swipe((100, 100), (200, 200)) Custom swiping duration and number of steps(Android and iOS):: >>> # swiping lasts for 1 second, divided into 6 steps >>> swipe((100, 100), (200, 200), duration=1, steps=6) """ 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() return pos1, pos2
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 """ try_log_screen() G.DEVICE.pinch(in_or_out=in_or_out, center=center, percent=percent) delay_after_operation()
def snapshot(filename=None, msg="", quality=None, max_size=None): """ 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 :param quality: The image quality, integer in range [1, 99], default is 10 :param max_size: the maximum size of the picture, e.g 1200 :return: {"screen": filename, "resolution": resolution of the screen} or None :platforms: Android, iOS, Windows :Example: >>> snapshot(msg="index") >>> # save the screenshot to test.jpg >>> snapshot(filename="test.png", msg="test") The quality and size of the screenshot can be set:: >>> # Set the screenshot quality to 30 >>> ST.SNAPSHOT_QUALITY = 30 >>> # Set the screenshot size not to exceed 600*600 >>> # if not set, the default size is the original image size >>> ST.IMAGE_MAXSIZE = 600 >>> # The quality of the screenshot is 30, and the size does not exceed 600*600 >>> touch((100, 100)) >>> # The quality of the screenshot of this sentence is 90 >>> snapshot(filename="test.png", msg="test", quality=90) >>> # The quality of the screenshot is 90, and the size does not exceed 1200*1200 >>> snapshot(filename="test2.png", msg="test", quality=90, max_size=1200) """ if not quality: quality = ST.SNAPSHOT_QUALITY if not max_size and ST.IMAGE_MAXSIZE: max_size = ST.IMAGE_MAXSIZE if filename: if not os.path.isabs(filename): logdir = ST.LOG_DIR or "." filename = os.path.join(logdir, filename) screen = G.DEVICE.snapshot(filename, quality=quality, max_size=max_size) return try_log_screen(screen, quality=quality, max_size=max_size) else: return try_log_screen(quality=quality, max_size=max_size)
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 filename: if not os.path.isabs(filename): logdir = ST.LOG_DIR or "." filename = os.path.join(logdir, filename) screen = G.DEVICE.snapshot(filename) return try_log_screen(screen) else: return try_log_screen()
def double_click(v): """ Perform double click :param v: target to touch, either a ``Template`` instance or absolute coordinates (x, y) :return: finial position to be clicked :Example: >>> double_click((100, 100)) >>> double_click(Template(r"tpl1606730579419.png")) """ if isinstance(v, Template): pos = loop_find(v, timeout=ST.FIND_TIMEOUT) else: try_log_screen() pos = v G.DEVICE.double_click(pos) delay_after_operation() return pos
def touch(v, times=1, **kwargs): """ Perform the touch action on the device screen :param v: target to touch, either a Template instance or absolute coordinates (x, y) :param times: how many touches to be performed :param kwargs: platform specific `kwargs`, please refer to corresponding docs :return: None :platforms: Android, Windows, iOS """ if isinstance(v, Template): pos = loop_find(v, timeout=ST.FIND_TIMEOUT) else: try_log_screen() pos = v for _ in range(times): G.DEVICE.touch(pos, **kwargs) time.sleep(0.05) delay_after_operation()
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()
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()
def touch(v, times=1, **kwargs): """ Perform the touch action on the device screen :param v: target to touch, either a ``Template`` instance or absolute coordinates (x, y) :param times: how many touches to be performed :param kwargs: platform specific `kwargs`, please refer to corresponding docs :return: finial position to be clicked :platforms: Android, Windows, iOS :Example: Click absolute coordinates:: >>> touch((100, 100)) Click the center of the picture(Template object):: >>> touch(Template(r"tpl1606730579419.png", target_pos=5)) Click 2 times:: >>> touch((100, 100), times=2) Under Android and Windows platforms, you can set the click duration:: >>> touch((100, 100), duration=2) Right click(Windows):: >>> touch((100, 100), right_click=True) """ if isinstance(v, Template): pos = loop_find(v, timeout=ST.FIND_TIMEOUT) else: try_log_screen() pos = v for _ in range(times): G.DEVICE.touch(pos, **kwargs) time.sleep(0.05) delay_after_operation() return pos
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 :Example: Pinch in the center of the screen with two fingers:: >>> pinch() Take (100,100) as the center and slide out with two fingers:: >>> pinch('out', center=(100, 100)) """ try_log_screen() G.DEVICE.pinch(in_or_out=in_or_out, center=center, percent=percent) delay_after_operation()