学习笔记-BasePage封装

1. 如何封装page

  • 实现通用的page方法,对常用自动化做封装
  • 管理各种driver
  • 减少每个page对appium,selenium等库的依赖

2. 自动化行为封装

  • 异常弹框处理
  • 通过自动化能力封装

3. BasePage构成

  • 类的属性:各个元素的定位
  • 类的方法:各个元素的操作方法

4. 优点

  • 当某页面元素发生变化,只需要修改页面中的元素的定位,不需修改测试用例
  • 提高代码重用性,结构更加清晰
  • 测试用例发生变化,只需修改少数页面对象

5. BasePage示例

# -*- coding: utf-8 -*-#
# -----------------------
# Name: demo
# Description:  封装所有页面的公共方法
# Author: sofi
# Date: 2019-11-05
# -----------------------
import os
import time
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from Common.read_yaml_tool import ReadYamlTool
from Common.path_tool import screenshot_path
from Common.read_config_tool import ReadConfigTool


class BasePage:
    def __init__(self, apk_name):
        # 初始化webdriver
        if apk_name == 'client':
            self.readConf = ReadConfigTool('apk_client_info.ini')
            self.host = self.readConf.get_option_value('Client_DeviceConf', 'remoteHost')
            self.desired_cap = self.readConf.get_conf_dump_dict()['Client_DeviceConf']

        elif apk_name == 'launcher':
            self.readConf = ReadConfigTool('apk_launcher_info.ini')
            self.host = self.readConf.get_option_value('Launcher_DeviceConf', 'remoteHost')
            self.desired_cap = self.readConf.get_conf_dump_dict()['Launcher_DeviceConf']

        try:
            self.driver = webdriver.Remote(self.host, self.desired_cap)

            # 隐式等待10秒
            self.driver.implicitly_wait(10)
            print('当前activity:{}'.format(self.driver.current_activity))
            self.driver.wait_activity('com.sudiyi.apps.launcher.IndexActivity',10)
            # 返回driver
            # return self.driver

        except Exception as e:
            print('[ERROR]-生成DRIVER失败..原因:{}'.format(e))

    '''====================================元素定位函数===================================='''

    def find_element(self, pagename, elename):
        '''
        查找元素
        :param pagename:页面名称
        :param elename:  元素名称
        :return:
        '''
        #读取元素信息
        ele_info = self.get_ele_info(pagename,elename)
        # print(ele_info[0])
        if ele_info[0] == 'By.ID':
            BY_KEY = By.ID
        elif ele_info[0] == 'By.XPATH':
            BY_KEY = By.XPATH
        elif ele_info[0] == 'By.NAME':
            BY_KEY = By.NAME
        elif ele_info[0] == 'By.CLASS_NAME':
            BY_KEY = By.CLASS_NAME
        elif ele_info[0] == 'By.CSS_SELECTOR':
            BY_KEY = By.CSS_SELECTOR

        BY_VALUE = ele_info[1]
        ele_info = (BY_KEY,BY_VALUE)

        try:
            # if 'id' in elename:
            #     ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_id(ele_info))
            #
            #
            # elif 'name' in elename:
            #     ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_name(ele_info))
            #
            # elif 'class_name' in elename:
            #     ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_class_name(ele_info))
            #
            # elif 'xpath' in elename:
            #     ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(ele_info))
            #
            # elif 'accessbility' in elename:
            #     ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_accessibility_id(ele_info))
            WebDriverWait(self.driver, 10,1).until(EC.presence_of_element_located(ele_info))
            loc = self.driver.find_element(*ele_info)
            print(loc)

            return loc

        except Exception as e:
            print('[ERROR]-查找元素{}失败,具体原因:{}'.format(elename, e))

    def check_ele_is_show(self,pagename,elename):
        '''
        检查元素是否显示
        :param page: 页面名称
        :param elename: 元素名称
        :return:
        '''
        if self.find_element(pagename,elename):
            return True
        else:
            return False

    '''====================================元素操作函数===================================='''
    def click_element(self,pagename,elename):
        try:
            #点击页面元素
            ele = self.find_element(pagename,elename)
            ele.click()

        except Exception as e:
            print('[ERROR]-点击页面元素{}失败,原因:{}'.format(elename,e))

    def click_one_of_elements(self,pagename,elename,index):
        '''
        点击元素集中的某一个元素
        :param pagename:
        :param elename:
        :param index: 元素下标
        :return:
        '''
        try:
            elements = self.find_elements(pagename,elename)
            ele = elements[index]
            ele.click()

        except Exception as e:

            print('[ERROR]-点击页面元素{}失败,原因:{}'.format(elename, e))


    def long_press_element(self,pagename,elename,duration=1000):
        '''
        长按元素
        :param pagename:
        :param elename:
        :return:
        '''
        try:
            ele = self.find_element(pagename,elename)
            TouchAction(self.driver).long_press(ele,duration).perform()


        except Exception as e:

            print('[ERROR]-长按页面元素{}失败,原因:{}'.format(elename, e))

    def clear_element(self,pagename,elename):
        try:
            #元素清空
            ele = self.find_element(pagename,elename)
            ele.clear()

        except Exception as e:
            print('[ERROR]-清空页面元素{}失败,原因:{}'.format(elename,e))


    def sendkeys(self,pagename,elename,content, clear_first=True, click_first=True):
        try:
            #输入元素信息
            ele = self.find_element(pagename,elename)
            if click_first:
                ele.click()
            if clear_first:
                ele.clear()
                ele.send_keys(content)

        except Exception as e:
            print('[ERROR]-输入信息失败,原因:{}'.format(elename,e))

    def is_toast_exist(self, text):
        '''is toast exist, return True or False
        :Agrs:
         - driver - 传driver
         - text   - 页面上看到的文本内容
         - timeout - 最大超时时间,默认30s
         - poll_frequency  - 间隔查询时间,默认0.5s查询一次
        :Usage:
         is_toast_exist(driver, "看到的内容")
        '''
        try:
            toast_loc = (By.XPATH, ".//*[contains(@text,'%s')]" % text)
            WebDriverWait(self.driver, 20, 0.01).until(EC.presence_of_element_located(toast_loc))
            return True
        except Exception as e:
            print(e)
            return False




    def tap_element(self,pagename,elename_x,elename_y,msec):
        '''

        :param pagename:
        :param elename_x: 横坐标
        :param elename_y: 纵坐标
        :param msec:点击频率
        :return:
        '''
        x = self.get_ele_info(pagename,elename_x)
        y = self.get_ele_info(pagename, elename_y)
        self.driver.tap([x, y], msec)

    def get_element_size(self,pagename,elename):
        '''
        获取元素的大小
        :param pagename:
        :param elename:
        :return:
        '''
        element_size = self.find_element(pagename,elename).size
        element_width = element_size.get('width')
        element_height = element_size.get('height')
        return element_width, element_height

    def get_window_size(self):
        size = self.driver.get_window_size()
        width = size['width']
        height = size['height']

        return width,height


    def swipe_screen(self,start_x,start_y,end_x,end_y,msec):
        '''
        滑动屏幕
        :param start_x: 元素左上方的x坐标
        :param start_y: 元素左上方的y坐标
        :param end_x: 元素右下方的x坐标
        :param end_y: 元素右下方的y坐标
        :param msec: 滑动频率,毫秒为单位,一般设置500-1000毫秒比较合适。
        '''
        self.driver.swipe(start_x,start_y,end_x,end_y,duration=msec)

    def swipe_right(self,start_x=0.1,end_x=0.9,duration=2000):
        '''向右滑动'''
        x = self.get_window_size()[0]
        y = self.get_window_size()[1]
        x1 = int(x*start_x)
        x2 = int(x*end_x)
        y1 = int(y * 0.5)
        y2 = int(y * 0.5)
        self.swipe_screen(x1,y1,x2,y2,duration)

    def swipe_left(self,start_x=0.9,end_x=0.1,duration=2000):
        '''向左滑动'''
        x = self.get_window_size()[0]
        y = self.get_window_size()[1]
        x1 = int(x * start_x)
        x2 = int(x * end_x)
        y1 = int(y * 0.5)
        y2 = int(y * 0.5)
        self.swipe_screen(x1, y1, x2, y2, duration)

    def swipe_up(self,start_y=0.9,end_y=0.1,duration=2000):
        '''向上滑动'''
        x = self.get_window_size()[0]
        y = self.get_window_size()[1]
        x1 = int(x * 0.5)
        x2 = int(x * 0.5)
        y1 = int(y * start_y)
        y2 = int(y * end_y)
        self.swipe_screen(x1, y1, x2, y2, duration)

    def swipe_down(self,start_y=0.1,end_y=0.9,duration=2000):
        '''向下滑动'''
        x = self.get_window_size()[0]
        y = self.get_window_size()[1]
        x1 = int(x * 0.5)
        x2 = int(x * 0.5)
        y1 = int(y * start_y)
        y2 = int(y * end_y)
        self.swipe_screen(x1, y1, x2, y2, duration)

    def get_element_location(self,pagename,elename):
        '''
        获取元素位置
        :param pagename:
        :param elename:
        :return:
        '''
        element_pos = self.find_element(pagename,elename).location
        element_x = element_pos.get('x')
        element_y = element_pos.get('y')
        return element_x, element_y

    '''====================================模拟按键函数===================================='''
    def press_HomeButton(self):
        '''按下Home键'''
        self.driver.press_keycode('3')

    def press_BackButton(self):
        '''按下返回键'''
        self.driver.press_keycode('4')

    def press_SearchButton(self):
        '''按下搜索键'''
        self.driver.press_keycode('84')

    def press_EnterButton(self):
        '''按下回车键'''
        self.driver.press_keycode('66')

    def press_DelButton(self):
        '''按下删除键'''
        self.driver.press_keycode('67')


    '''====================================截图操作函数===================================='''
    def _nowtime(self):
        nowtime = time.strftime('%Y%m%d_%H%M%S')
        return nowtime


    def take_screenshot(self,filename):
        '''

        :param filename:文件名
        :return:
        '''
        try:
            nowtime = self._nowtime()
            file_path = os.path.join(screenshot_path,'{}_{}.png'.format(filename,nowtime))
            self.driver.get_screenshot_as_file(file_path)


        except Exception as e:

            print('[ERROR]-截图失败,原因:{}'.format(e))


    '''====================================页面操作函数===================================='''

    def switch_to_webview(self):
        '''切换到webview'''
        for i in range(1):
            print(self.driver.contexts)
            time.sleep(1)
            # WebDriverWait(self.driver,20).until(expected_conditions.visibility_of_element_located((By.ID)))
        webview = self.driver.contexts[-1]
        # print(webview)

        # #切换到webview
        self.driver.switch_to.context(webview)

    def switch_to_native_view(self):
        # 切换到nativeview
        self.driver.switch_to.context(self.driver.contexts[0])

    def get_ele_info(self,pagename,elename):
        '''
        读取元素信息
        :param page: 页面名称
        :param elename: 元素名称
        :return:
        '''
        read_yaml = ReadYamlTool('ElementsData', pagename)
        ele_info = read_yaml.get_yaml_all_items(elename)

        return ele_info

    def quit_driver(self):
        self.driver.quit()


if __name__ == '__main__':
    tool = BasePage('launcher')
    # print(tool.find_element('HomePage.yaml', 'ele_btn1_id'))
    # tool.find_elements('HomePage.yaml', 'ele_btn1_id','ele_btn2_id')
    # tool.find_element('HomePage.yaml', 'ele_btn1_id')

你可能感兴趣的:(学习笔记-BasePage封装)