天天看點

python+uiautomator2二次封裝

python+uiautomator2二次封裝

#!python3.7
# -*- coding: utf-8 -*-

__author__ = 'haiertamendie'
__data__ = "2019-11-15 19-56"

import base64

"""
界面元素基礎操作
"""
import uiautomator2 as u2
from Config.Config import Config
from Api.Public.PyApiLog import PyApiLog
import datetime
import os
import time
from unittest import TestCase


class Action:
    def __init__(self):
        pass

    def connect_wifi(self, ip):
        """
        通過WiFi連接配接裝置:ip根據情況自己修改
        :param ip:
        :return:
        """
        return u2.connect_wifi(ip)

    def connect_usb(self):
        """
        通過USB連接配接裝置
        :return:
        """
        return u2.connect_usb()

    def healthcheck(self):
        """
        檢查并維持裝置端守護程序處于運作狀态
        :return:
        """
        self.device.healthcheck()

    def app_start(self, package_name,
                  activity=None,
                  extras={},
                  wait=True,
                  stop=True,
                  unlock=False,
                  launch_timeout=30,
                  use_monkey=False):
        """
        啟動APP
        :param package_name:
        :param activity:
        :param extras:
        :param wait:
        :param stop:
        :param unlock:
        :param launch_timeout:
        :param use_monkey:
        :return:
        """
        self.device.app_start(package_name, activity=activity, extras=extras, wait=wait, stop=stop, unlock=unlock,
                              launch_timeout=launch_timeout, use_monkey=use_monkey)

    def app_stop(self, package_name):
        """
        關閉app
        :param package_name: 應用包名
        :return:
        """
        self.device.app_stop(package_name)

    def app_clear(self, package_name):
        """
        清除app緩存
        :param package_name: 應用包名
        :return:
        """
        self.device.app_clear(package_name)

    def get_app_info(self, package_name):
        """
        擷取應用資訊
        :param package_name: 應用包名
        :return:
        """
        return self.device.app_info(package_name)

    def app_stop_all(self, excludes=[]):
        """
        關閉excludes中的所有應用
        :param excludes: 應用包名集合
        :return:
        """
        self.device.app_stop_all(excludes)

    def get_app_list_running(self):
        """
        擷取已啟動的應用
        :return:
        """
        return self.device.app_list_running()

    def wait_activity(self, activity, timeout=10):
        """
        等待activity加載出來
        :param activity:
        :param timeout:
        :return:
        """
        self.wait_activity(activity=activity, timeout=timeout)

    def app_wait(self, package_name, timeout=20.0,
                 front=False):
        """
        等待應用啟動
        :param package_name: 應用包名
        :param timeout:  逾時時間
        :param front:
        :return:
        """
        return self.device.app_wait(package_name, timeout=timeout, front=front)

    def app_insatll(self, url, installing_callback=None, server=None):
        """
        安裝應用
        :param url: 裝置名字或者位址
        :param installing_callback:
        :param server:
        :return:
        """
        self.device.app_install(url, installing_callback=installing_callback, server=server)

    def app_uninstall(self, package_name):
        """
        解除安裝應用
        :param package_name: 應用包名
        :return:
        """
        self.device.app_uninstall(package_name)

    def app_uninstall_all(self, excludes=[], verbose=False):
        """
        解除安裝多個應用
        :param excludes: 應用包名集合
        :param verbose:
        :return:
        """
        self.device.app_uninstall_all(excludes=excludes, verbose=verbose)

    def get_element_xpath(self, xpath):
        """
        根絕xpath路徑擷取元素
        :param xpath: xpath路徑
        :return:
        """
        return self.device.xpath(xpath)

    def get_elements(self, childCount=None, **kwargs):
        """擷取元素
        @:param childCount 子元素數量
        """
        ele = self.device(**kwargs)
        if childCount:
            eles = []
            for i in ele:
                if i.info.get("childCount") == childCount:
                    eles.append(i)
            return eles
        else:
            return ele

    def get_count(self, **kwargs):
        """
        擷取元素個數
        :param kwargs: 元素定位
        :return:
        """
        return self.device(**kwargs).count

    def get_child_element(self, element, childCount=None, **kwargs):
        """
        擷取子對象
        :param element: 元素對象
        :param childCount:
        :param kwargs:
        :return:
        """
        ele = element.child(**kwargs)
        if childCount == None or len(ele) == 1:
            return ele
        else:
            eles = []
            for i in ele:
                if i.info.get("childCount") == childCount:
                    eles.append(i)
            return eles

    def get_left_element(self, element, **kwargs):
        """
        擷取element左側元素
        :param element: 元素對象
        :param kwargs:
        :return:
        """
        return element.left(**kwargs)

    def get_right_element(self, element, **kwargs):
        """擷取element右側元素"""
        return element.right(**kwargs)

    def get_up_element(self, element, **kwargs):
        """
        擷取element上方元素
        :param element: 元素對象
        :param kwargs:
        :return:
        """
        return element.up(**kwargs)

    def get_down_element(self, element, **kwargs):
        """
        擷取element下方元素"
        :param element: 元素對象
        :param kwargs: 
        :return: 
        """""
        return element.down(**kwargs)

    def get_sibling_elements(self, index=0, **kwargs):
        """
        擷取兄弟元素
        :param index: 第幾個兄弟,預設為全部
        :param kwargs: 元素定位(唯一)
        :return:
        """
        self.wait(**kwargs)
        if index == 0:
            return self.device(**kwargs).sibling()
        return self.device(**kwargs).sibling()[index]

    def get_sibling_elements_by_element(self, element, **kwargs):
        """
        擷取兄弟元素
        :param element: 元素
        :param kwargs: 兄弟元素定位(唯一)
        :return:
        """
        return element.sibling(**kwargs)

    def click(self, **kwargs):
        """
        點選元素
        :param index: 索引值
        :param kwargs: 元素定位()
        :return:
        """
        self.device(**kwargs).click()

    def click_xpath(self, xpath, timeout=5):
        """
        根據xpath路徑點選元素
        :param xpath:
        :param timeout:
        :return:
        """
        self.device.xpath(xpath).click(timeout=timeout)

    def click_element(self, element):
        """
        點選元素
        :param element: 元素對象
        :return:
        """
        element.click()

    def click_child_element(self, element, **kwargs):
        """
        點選element的子元素
        :param element: 元素對象
        :param kwargs: 子元素定位資訊
        :return:
        """
        ele = self.get_child_element(element, **kwargs)[0]
        self.click_element(ele)

    def click_by_point(self, x, y):
        """
        點選坐标點
        :param x: 橫坐标
        :param y: 縱坐标
        :return:
        """
        self.device.click(x, y)

    def double_click(self, x, y, duration=0.1):
        """輕按兩下
        @:param duration 間隔
        """
        self.device.double_click(x, y, duration=duration)

    def long_click(self, duration=10, timeout=10, **kwargs):
        """
        長按指定的對象
        :param duration: 持續時間
        :param timeout: 逾時時間
        :param kwargs: 元素定位
        :return:
        """
        self.device(**kwargs).long_click(duration=duration, timeout=timeout)

    def long_click_by_element(self, element, duration=10, timeout=10):
        """
        長按
        :param element: 元素對象
        :param duration: 持續時間
        :param timeout: 逾時時間
        :return:
        """
        element.long_click(duration=duration, timeout=timeout)

    def long_click_by_point(self, x, y):
        """
        長按坐标點
        :param x: 橫坐标
        :param y: 縱坐标
        :return:
        """
        self.device.long_click(x, y)

    def get_element_info(self, **kwargs):
        """
        擷取元素資訊
        :param kwargs: 元素定位
        :return:
        """
        return self.device(**kwargs).info

    def get_info_by_element(self, element):
        """
        擷取元素資訊
        :param element: 元素對象
        :return:
        """
        return element.info

    def input_text(self, content, **kwargs):
        """
        輸入文本
        :param content: 文本内容
        :param kwargs: 元素定位資訊
        :return:
        """
        self.wait(**kwargs)
        self.device(**kwargs).set_text(content)
        self.press("enter")

    def input_text_xpath(self, content, xpath):
        """
        輸入文本
        :param content: 文本内容
        :param xpath: 元素xpath定位資訊
        :return:
        """
        self.wait_xpath(xpath)
        element = self.get_element_xpath(xpath)
        self.click_element(element)
        element.set_text(content)

    def input_text_by_element(self, element, content):
        """輸入"""
        self.click_element(element)
        element.set_text(content)
        self.press("enter")

    def clear_text(self, **kwargs):
        """
        清除輸入框資料
        :param kwargs: 輸入文本框定位
        :return:
        """
        self.device(**kwargs).clear_text()

    def clear_text_by_element(self, element):
        """清除資料"""
        element.clear_text()

    def click0(self, **kwargs):
        """點選UI對象中心位置"""
        self.device(**kwargs).click0()

    def click0_by_element(self, element):
        """點選UI對象中心位置"""
        element.click0()

    def click_bottomright(self, **kwargs):
        """點選UI對象右下角"""
        self.device(**kwargs).click.bottomright()

    def click_bottomright_by_element(self, element):
        """點選UI對象右下角"""
        element.click.bottomright()

    def click_topleft(self, **kwargs):
        """點選UI對象左上角"""
        self.device(**kwargs).click.topleft()

    def click_topleft_by_element(self, element):
        """點選UI對象左上角"""
        element.click.topleft()

    def long_click_bottomright(self, **kwargs):
        """長按UI對象右下角"""
        self.device(**kwargs).long_click.bottomright()

    def long_click_bottomright_by_element(self, element):
        """長按UI對象右下角"""
        element.long_click.bottomright()

    def long_click_topleft(self, **kwargs):
        """長按UI對象左上角"""
        self.device(**kwargs).long_click.topleft()

    def long_click_topleft_by_element(self, element):
        """長按UI對象左上角"""
        element.long_click.topleft()

    def drag_to_point(self, element, x, y, duration=1):
        """拖動指定對象到x,y位置,0.5s完成"""
        element.drag.to(x, y, duration=duration)

    def drag_to_element(self, element, **kwargs):
        """拖拽某一UI對象到另外一個UI對象(中心)"""
        element.drag.to(**kwargs, steps=100)

    def refresh(self):
        """重新整理頁面"""
        wedith = self.get_window_size()[0]
        height = self.get_window_size()[1]
        self.swipe(wedith / 2, height * 1 / 4, wedith / 2, height * 5 / 6)

    def swipe_right(self, **kwargs):
        """從UI對象的中心滑動到UI對象的右邊緣"""
        self.device(**kwargs).swipe.right()

    def swipe_right_by_element(self, element):
        """從UI對象的中心滑動到UI對象的右邊緣"""
        element.swipe.right()

    def swipe_up(self, **kwargs):
        """從UI對象的中心滑動到UI對象的上邊緣"""
        self.device(**kwargs).swipe.up()

    def swipe_up_screen(self, scre=1, steps=100):
        """
        向上滑動螢幕,預設為一屏
        :param scre: 滑動比例
        :return:
        """
        device_info = self.get_device_info()
        height = device_info.get("displayHeight")
        width = device_info.get("displayWidth")
        self.device.swipe(width / 2, height * 8 * scre / 9, width / 2, height / 9, steps=steps)

    def swipe_down_screen(self, scre=1, steps=100):
        """
        向下滑動螢幕,預設為一屏
        :param scre: 滑動比例
        :return:
        """
        device_info = self.get_device_info()
        height = device_info.get("displayHeight")
        width = device_info.get("displayWidth")
        self.device.swipe(width / 2, height / 9, width / 2, height * 8 * scre / 9, steps=steps)

    def swipe_up_by_element(self, element):
        """從UI對象的中心滑動到UI對象的上邊緣"""
        element.swipe.up()

    def swipe_left(self, **kwargs):
        """從UI對象的中心滑動到UI對象的左邊緣"""
        self.device(**kwargs).swipe.left()

    def swipe_left_by_element(self, element):
        """從UI對象的中心滑動到UI對象的左邊緣"""
        element.swipe.left()

    def swipe_down(self, **kwargs):
        """從UI對象的中心滑動到UI對象的下邊緣"""
        self.device(**kwargs).swipe.down()

    def swipe_down_by_element(self, element):
        """從UI對象的中心滑動到UI對象的下邊緣"""
        element.swipe.down()

    def pinch_In(self, **kwargs):
        """從邊緣到中心"""
        self.device(**kwargs).pinch.In(percent=100, steps=10)

    def pinch_In_by_element(self, element):
        """從邊緣到中心"""
        element.pinch.In(percent=100, steps=10)

    def pinch_Out(self, percent=33, steps=100):
        """從螢幕外側向中心滑動,percent為左右起始位置占兩邊的比例"""
        self.device().pinch_out(percent=percent, steps=steps)

    def pinch_Out_element(self, element, percent=33, steps=100):
        """從中心到邊緣"""
        element.pinch_out(percent=percent, steps=steps)

    def set_implicitly_wait(self, timeout=30):
        """設定全局最長等待時間"""
        return self.device.implicitly_wait(timeout)

    def click_wait(self, timeout=10, **kwargs):
        """
        當timeout s内對象出現就點選
        :param timeout: 逾時時間
        :param kwargs: 元素定位
        :return:
        """
        self.device(**kwargs).click_exists(timeout)

    def click_wait_xpath(self, xpath, timeout=10):
        """
        當timeout s内對象出現就點選
        :param xpath: xpath定位
        :param timeout: 逾時時間
        :return:
        """
        self.wait_xpath(xpath, timeout=timeout)
        self.click_xpath(xpath)

    def click_gone(self, maxretry=10, interval=1.0, **kwargs):
        """
        點選并輪詢對象直到消失
        :param maxretry: 最多點選次數
        :param interval: 輪詢時間間隔
        :param kwargs: 元素定位
        :return:
        """
        self.device(**kwargs).click_gone(maxretry=maxretry, interval=interval)

    def wait_exists_by_element(self, element, timeout=10):
        """
        等待UI對象出現
        :param element: 元素對象
        :param timeout: 逾時時間
        :return:
        """
        return element.exists(timeout=timeout)

    def wait(self, timeout=10, **kwargs):
        """
        等待
        :param timeout: 逾時時間
        :param kwargs: 元素定位
        :return:
        """
        return self.device(**kwargs).wait(timeout)

    def wait_should_be_contains(self, timeout=10, **kwargs):
        """
        等待包含元素,逾時抛出錯誤
        :param timeout: 逾時時間
        :param kwargs: 元素定位
        :return:
        """
        self.device(**kwargs).must_wait(exists=True, timeout=timeout)

    def wait_xpath(self, xpath, timeout=10):
        """
        等待
        :param xpath: xpath路徑
        :param timeout: 逾時時間
        :return:
        """
        return self.device.xpath(xpath).wait(timeout=timeout)

    def wait_gone(self, timeout=10, **kwargs):
        """
        等待UI對象消失
        :param timeout: 逾時時間
        :param kwargs: 元素定位
        :return:
        """
        return self.device(**kwargs).wait_gone(timeout=timeout)

    def wait_gone_xpath(self, xpath, timeout=10):
        """
        等待UI對象消失
        :param xpath: xpath定位
        :param timeout: 逾時時間
        :return:
        """
        return self.device.xpath(xpath).wait_gone(timeout=timeout)

    def wait_gone_by_element(self, element, timeout=3000):
        """
        等待UI對象消失
        :param element: 元素對象
        :param timeout: 逾時時間
        :return:
        """
        return element.wait_gone(timeout=timeout)

    def scroll_up(self, steps=10):
        """
        向上滑動
        :param steps: 步長
        :return:
        """
        self.device(scrollable=True).scroll(steps=steps)

    def scroll_up_to_content_element(self, max_scroll_num=15, **kwargs):
        """
        向上滑動直到某個元素出現
        :param max_scroll_num: 最大滑動次數
        :param kwargs: 元素定位
        :return:
        """
        self.sleep()
        num = 0
        while num < max_scroll_num:
            if self.exists(timeout=0.5, **kwargs):
                return True
            else:
                try:
                    self.swipe_up_screen(0.5, steps=20)
                except:
                    return False
            num = num + 1
            self.sleep(0.2)
        if num == max_scroll_num:
            return False
        else:
            return True

    def vert_backward(self):
        """
        向下滑動
        :return:
        """
        self.device(scrollable=True).scroll.vert.backward()

    def vert_backward_to_content_element(self, **kwargs):
        """
        向下滑動直到某個元素出現
        :param kwargs: 元素定位
        :return:
        """
        while True:
            if self.exists(**kwargs):
                break
            else:
                self.device(scrollable=True).scroll.vert.backward(steps=100)

    def scroll_to_beginning(self, steps=10, max_swipes=1000):
        """
        向左滑動到開始位置
        :param steps: 步長
        :param max_swipes:
        :return:
        """
        self.device(scrollable=True).scroll.horiz.toBeginning(steps=steps, max_swipes=max_swipes)

    def horiz_forward(self, steps=10):
        """
        向右滑動"
        :param steps: 步長
        :return: 
        """""
        self.device(scrollable=True).scroll.horiz.forward(steps=steps)

    def scroll_to_end(self, steps=10):
        """
        向結束方向滑動
        :param steps: 步長
        :return:
        """
        self.device(scrollable=True).scroll.toEnd(steps=steps)

    def scroll_to(self, **kwargs):
        """
        向前滾動到指定UI位置
        :param kwargs: 元素定位
        :return:
        """
        self.device(scrollable=True).scroll.to(**kwargs)

    def get_device_info(self):
        """
        擷取裝置資訊
        :return:
        """
        return self.device.info

    def get_window_size(self):
        """
        擷取視窗大小
        :return:
        """
        return self.device.window_size()

    def get_device_height(self):
        """
        擷取裝置的高度
        :return:
        """
        return self.device.info.get("displayHeight")

    def get_device_width(self):
        """
        擷取裝置的寬度
        :return:
        """
        return self.device.info.get("displayWidth")

    def screen_on(self):
        """
        打開螢幕
        :return:
        """
        self.device.screen.on()

    def screen_off(self):
        """
        關閉螢幕
        :return:
        """
        self.device.screen.off()

    def wakeup(self):
        """
        喚醒裝置
        :return:
        """
        self.device.wakeup()

    def device_sleep(self):
        """
        關閉裝置
        :return:
        """
        self.device.sleep()

    def sleep(self, seconds=2):
        """
        強制等待時間
        :param seconds:
        :return:
        """
        time.sleep(seconds)

    def press_home(self):
        """
        按home鍵
        :return:
        """
        self.device.press("home")

    def press_back(self):
        """
        按傳回鍵
        :return:
        """
        self.device.press("back")

    def press(self, key):
        """
        按下鍵碼
        :param key: 鍵碼值
        :return:
        """
        self.device.press(key)

    def press_enter(self):
        """
        按下Enter鍵
        :return:
        """
        self.device.press.enter()

    def swipe(self, sx, sy, ex, ey, steps=10):
        """
        從sx,sy坐标滑動至ex,ey坐标
        :param sx: 起點橫坐标
        :param sy: 起點縱坐标
        :param ex: 終點橫坐标
        :param ey: 終點縱坐标
        :param steps:
        :return:
        """
        self.device.swipe(sx, sy, ex, ey, steps=steps)

    def gesture(self, a, b, c, d, a1, b1, c1, d1, steps=100):
        """
        雙指從(a,b),(c,d)滑動(a1,b1),(c1,d1),步長100
        :param a:
        :param b:
        :param c:
        :param d:
        :param a1:
        :param b1:
        :param c1:
        :param d1:
        :param steps:
        :return:
        """
        self.device.gesture((a, b), (c, d), (a1, b1), (c1, d1), steps=steps)

    def drag(self, sx, sy, ex, ey, steps=10):
        """
        從sx,sy坐标拖動至ex,ey坐标
        :param sx: 起點橫坐标
        :param sy: 起點縱坐标
        :param ex: 終點橫坐标
        :param ey: 終點縱坐标
        :param steps: 步長
        :return:
        """
        self.device.drag(sx, sy, ex, ey, steps=steps)

    def screenshot(self, name=""):
        """
        截屏
        :param name: 圖檔名字
        :return:
        """
        if name != "":
            path = os.path.join(self.path_screenshot, name + ".png")
        else:
            path = os.path.join(self.path_screenshot, datetime.datetime.now().strftime('%Y-%m-%d_%H_%M') + ".png")
        self.device.screenshot(path)

    def get_screenshot_as_base64(self):
        """
        截屏并轉換成base64
        :return:
        """
        content = self.device.screenshot(format="raw")
        base64_data = base64.b64encode(content)
        # base64.b64decode(base64data)
        return str(base64_data, "utf-8")

    def dump(self, path):
        """
        将目前螢幕結構儲存在本機,xml檔案
        :param path: 儲存路徑
        :return:
        """
        self.device.dump_hierarchy(path)

    def notification(self):
        """
        打開通知消息
        :return:
        """
        self.device.notification()

    def open_quick_settings(self):
        """
        打開快捷設定欄
        :return:
        """
        self.device.open.quick_settings()

    def register_watcher_click(self, name, **kwargs):
        """
        建立并運作監聽器
        :param name:
        :param kwargs:
        :return:
        """
        watcher = self.device.watcher(name).when(**kwargs).click(**kwargs)
        self.watchers_run()
        return watcher

    def remove_watcher(self, name):
        """
        移除監聽器
        :param name: 監聽器名字
        :return:
        """
        self.device.watcher(name).remove()

    def watchers(self):
        """
        擷取所有監聽器
        :return:
        """
        return self.device.watcher()

    def watchers_triggered(self, name):
        """
        擷取所有已觸發監聽器
        :param name:
        :return:
        """
        return self.device.watcher(name).triggered

    def watchers_reset(self):
        """
        重置所有已觸發的螢幕
        :return:
        """
        self.device.watchers.reset()

    def watchers_run(self):
        """
        運作所有已注冊的監聽器
        :return:
        """
        self.device.watchers.run()

    def exists(self, timeout=10, **kwargs):
        """
        判斷元素是否存在
        :param timeout: 逾時時間
        :param kwargs: 元素定位
        :return:
        """
        return self.device(**kwargs).exists(timeout=timeout)

    def exists_xpath(self, xpath):
        """
        判斷元素是否存在
        :param xpath: xpath路徑
        :return:
        """
        return self.device.xpath(xpath).exists

    def wait_not_exists(self, timeout=15, **kwargs):
        """
        等待元素消失
        :param timeout: 逾時時間
        :param kwargs: 元素定位
        :return:
        """
        num = 1
        while num <= timeout * 2:
            if self.exists(**kwargs):
                self.sleep(0.5)
                num = num + 1
            else:
                return True
        return False

    def exists_by_element(self, element, timeout=10):
        """
        判斷元素是否存在
        :param element: 元素對象
        :param timeout: 逾時時間
        :return:
        """
        return element.exists(timeout=timeout)

    def disable_popups(self, disable=True):
        """彈出視窗
        @:param disable True:自動跳過彈出視窗,False:禁用自動跳過彈出視窗
        """
        self.device.disable_popups(disable)

    def get_toast(self, wait_timeout=15,
                  cache_timeout=8,
                  default=None):
        """
        擷取toast提示
        :param wait_timeout: 逾時時間
        :param cache_timeout: 從現在開始多少時間以内
        :param default: 逾時提示
        :return:
        """
        toast = self.device.toast.get_message(wait_timeout=wait_timeout,
                                              cache_timeout=cache_timeout,
                                              default=default)
        if toast:
            self.reset_toast()
        return toast

    def reset_toast(self):
        """
        清除裝置toast提示
        :return:
        """
        self.device.toast.reset()

           

更多系列文章:https://blog.csdn.net/qq_33676825