selenium+pytest:Web自动化框架设计及元素操作封装(一)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

一、目录结构及文件说明

在这里插入图片描述

二、元素操作类

import sys
from congfig.pub.AttributeEle import *
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
import logging.config
import os,datetime
from congfig.pub.FilePath import LOG_PATH_CON
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from tools.YamlTools import  OperationElementYaml
from tools.StaticFunction import StaticFunction as SF
from congfig.pub.FrontColour import FrontColour as FC
logging.config.fileConfig(LOG_PATH_CON)
#封装页面元素操作
class OperationPageElement():

    def __init__(self,driver) :
        self.driver = driver

    #获取元素操作类型,当前支持,ID、PATH、CLASS_NAME、NAME、CSS_SELECTOR、TAG_NAME
    def getByType(self,elType):
        #将字符串转换成大写
        elemnt_loc = elType.upper()
        if elemnt_loc == ID:
            return By.ID
        elif elemnt_loc ==XPATH:
            return By.XPATH
        elif elemnt_loc ==CLASS_NAME:
            return By.CLASS_NAME
        elif elemnt_loc == NAME:
            return By.NAME
        elif elemnt_loc ==CSS_SELECTOR:
            return By.CSS_SELECTOR
        elif elemnt_loc == TAG_NAME:
            return By.TAG_NAME
        else:
            logging.error(FC.RED%"元素定位类型不存在")
            sys.exit()


    #等待元素
    def waitElement(self,elType,element):
        try :
            #显示等待元素出现
            WebDriverWait(self.driver,5 ,0.5).until(EC.presence_of_element_located((elType,element)))
            logging.info("操作的元素类型:{0},元素值:{1},存在".format(elType,element))
            return True
        except Exception:
            logging.error(FC.RED%"时间内元素未出现,测试结束,当前元素:{0}".format(element))
            sys.exit()
    #操作页面元素param count,默认为None,1时,则说明有多个值,单个值调用find_element,多个值调用find_elements
    def operationElement(self,elType,element,count=0):
        elementType = self.getByType(elType)
        if self.waitElement(elementType,element):
            if count >= 1:

                elements_data = self.driver.find_elements(elementType,element)
                return elements_data
            else:
                element_data = self.driver.find_element(elementType,element)
                return element_data

    #对页面元素进行点击操作,若存在多个根据下标进行点击
    def  operationElementClick(self,**kwargs):
        #
        # if kwargs['func_attr'] =="select":
        #
        #     return self.__privateOperationSelectEl(type=type,element=element,count=count)
        #
        # elif func_attr =='list' :
        #     el = self.operationElement(elType=type, element=element, count=count)
        #     el_list = self.__privateOutputListData(el)
        #
        #     try:
        #         ActionChains(self.driver).move_to_element(el_list[0]).click().perform()
        #     except AttributeError:
        #         return False
        if kwargs['count'] >= 1:
            el = self.operationElement(elType=kwargs['el_types'], element=kwargs['element'], count=kwargs['count'])
            el_list = self.__checkElData(el)

            try:
                ActionChains(self.driver).move_to_element(el_list[kwargs['index'] - 1]).click().perform()
                # el_list[count-1].click()
            except Exception as e :

                logging.error(FC.RED%'元素执行点击事件失败,请检查页面元素,元素{0}'.format(kwargs['element']))
                sys.exit()
        else:
            el = self.operationElement(elType=kwargs['el_types'], element=kwargs['element'], count=kwargs['count'])
            try:
                ActionChains(self.driver).move_to_element(el).click().perform()
                # el.click()

            except AttributeError:
                logging.error(FC.RED%'元素执行点击事件失败,请检查页面元素,元素:{0}'.format(kwargs['element']))
                sys.exit()



    #对页面文本输入框传值,若存在多个则根据下标进行赋值(加for循环取值
    def operationElInputText(self,**kwargs):
        '''通过count和index组合判断是操作元素
        1.index=-1则判断为通过循环count数操作元素
        2.index !=-1则根据index 下标操作元素
        '''
        if kwargs['count'] >= 1 and kwargs['index'] !=-1:
            input_el = self.operationElement(elType=kwargs['el_types'], element=kwargs['element'],
                                             count=kwargs['count'])
            input_el[kwargs['index']].clear()
            SF.sleep_time(1)
            input_el[kwargs['index']].send_keys(kwargs['text'])
        elif kwargs['count'] >= 1 and kwargs['index'] ==-1:
            input_el = self.operationElement(elType=kwargs['el_types'], element=kwargs['element'], count=kwargs['count'])
            for i in range(len(input_el)):
                input_el[i].clear()
                SF.sleep_time(1)
                input_el[i].send_keys(kwargs['text'][i])
        else:
            input_el = self.operationElement(elType=kwargs['el_types'], element=kwargs['element'])
            input_el.send_keys(kwargs['text'])




    #针对元素列表长度大于一的进行处理,将空元素剔除,返回有文本的元素信息
    def __checkElData(self,element):
        #接收处理后的元素信息
        if isinstance(element,list):
            el_list =list(filter(lambda x: x!='',element))
            if len(el_list) ==0:
                return element
            else:
                return el_list
        else:
            logging.info('返回页面元素文本内容:'.format(element.text))
            return element.text
    #获取页面元素文本内容
    # def operationElementText(self,type,element,count,attribute=None,label=None):
    def operationElementText(self, **kwargs):

        if kwargs['attribute'] != None and kwargs['count'] ==0:
            element_data = self.operationElement(kwargs['type'],kwargs['element'],kwargs['count'])
            return element_data.getAttribute(kwargs['attribute'])

        elif kwargs['label'] != None and kwargs['count'] ==0:
            element_data = self.operationElement(kwargs['type'],kwargs['element'],kwargs['count'])
            return element_data.text

        elif kwargs['label']==None and kwargs['attribute'] ==None and kwargs['count']==0:
            element_data = self.operationElement(kwargs['type'],kwargs['element'],kwargs['count'])
            data = element_data.text
            list_data = data.split('\n')
            return list_data
        elif kwargs['label']==None and kwargs['attribute'] ==None and kwargs['count'] >=1:
            element_data = self.operationElement(kwargs['type'],kwargs['element'],kwargs['count'])
            #处理部分元素需要鼠标焦点后才能获取内容
            ActionChains(self.driver).move_to_element(element_data[kwargs['index']-1]).click(element_data[kwargs['index']-1]).perform()
            return element_data[kwargs['index']-1].text
        else:
            logging.error(FC.RED%"未获取到元素中文本内容")
            sys.exit()

    #通过select方法获取下拉框选项值
    def __privateOperationSelectEl(self,type,element,count):

        select_el = Select(self.operationElement(type, element, count))

        return select_el.select_by_index(count)


    #将list的元素中文进行输入打印
    def __privateOutputListData(self,element):
        # data = list(filter(lambda x: x.text !='', element))
        return list(filter(lambda x: x != '' and x.text !='', element))
    #封装元素的操作方法通过传入的操作类型调用不同的元素的操作
    def autoElement(self,**kwargs):
        if SF.checkOperationType(kwargs['operation_type']):
           if kwargs.get('operation_type') == INPUT:
                return  self.operationElInputText(**kwargs)
           elif kwargs.get('operation_type') ==CLICK:
                return self.operationElementClick(**kwargs)
           elif kwargs.get('operation_type') ==VALUE:
                return self.operationElementText(**kwargs)
        else:
            sys.exit(FC.RED%'当前元素操作类型不支持')

   #实例化yaml操作元素方法,执行元素操作
    def getYamElData(self,yamlName,funcName,text=None):

        el_data = OperationElementYaml(yamlName=yamlName,funcName=funcName)

        return self.autoElement(el_types=el_data.getElType,operation_type=el_data.getOperationType,
                                     element=el_data.getElement,count=el_data.getCount,
                                     attribute=el_data.getAttribute,label=el_data.getLabel,
                                    index=el_data.getIndex,text=text)

三、页面公共方法

该类主要封装一些鼠标和浏览器操作方法,并且继承OperationPageElement类

class OperationPageFunction(OperationPageElement):
    #强制休眠时间


    #操作页面多个窗口句柄,获取页面当前总句柄数,通过title将句柄封装成dict,格式{‘title名’:‘句柄信息’}
    @property
    def __operationWindowHandle(self):
        list_all_handle = self.driver.window_handles
        return list_all_handle

    #根据下标切换页面句柄
    def operationSwitchHandle(self,index):
        self.driver.switch_to.window(self.__operationWindowHandle[index])
        return None

    # 截图操作
    def getImage(self, pagename):
            path = os.path.dirname(os.path.dirname(__file__))
            current_time = datetime.datetime.now()
            time_str = datetime.datetime.strftime(current_time, '%Y-%m-%d_%H-%M-%S')
            image_file = path + '//Picture//' + pagename + '_' + time_str + '.png'
            try:
                self.driver.get_screenshot_as_file(image_file)
            except BaseException as e:
                logging.error(e)

    # 操作需要鼠标悬浮显示元素值
    def mouseAction(self, el_name):
            ActionChains(self.driver).move_to_element(el_name).click(el_name).perform()
            return None
    #操作鼠标点击页面按钮
    def mouseClick(self,el_name):
        ActionChains(self.driver).move_to_element(el_name).click(el_name)
        return None
    # 获取系统标题
    @property
    def getPageTitle(self):
            return self.driver.title

    # 获取系统url
    @property
    def getPageUrl(self):
            return self.driver.current_url

    # 获取页面所有元素,判断元素是否显示,显示返回True否则返回False
    def getPageSource(self, page_source):
            page_element = self.driver.page_source
            if page_source in page_element:
                return True
            else:
                return False

总结

新手小白一个方法还存在些问题在持续优化过程中

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值