python3+selenium二次封装调用

baseui工具类_封装selenium的常用方法

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import time
import allure
from selenium.webdriver import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By


# allure操作之前操作之后截图操作
def shot(func):
    def function(*args, **kwargs):
        allure.attach(
            args[0].driver.get_screenshot_as_png(),
            args[1] + '之前',
            allure.attachment_type.PNG)

        res = func(*args, **kwargs)
        allure.attach(
            args[0].driver.get_screenshot_as_png(),
            args[1] + '之后',
            allure.attachment_type.PNG)
        return res

    return function


# 二次封装selenium方法
class baseUI():

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

    def local_element(self, xpath):
        return WebDriverWait(
            self.driver, 5, 0.3).until(
            EC.presence_of_element_located(
                (By.XPATH, xpath)))

    @shot
    def send_keys(self, step, xpath, text):
        '''
        文本输入框清空并填值
        :param step:操作步骤
        :param xpath: xpath
        :param text: 填的值
        :return:
        '''
        element = self.local_element(xpath)
        element.clear()
        element.send_keys(text)

    @shot
    def click(self, step, xpath):
        '''
        #点击操作
        :param step: 操作步骤
        :param xpath: xpath
        :return:
        '''
        element = self.local_element(xpath)
        element.click()
        # self.driver.execute_script("arguments[0].click();", element)
        # ActionChains(self.driver).move_to_element(element).click(element).perform()

    @shot
    def scroll_screen(self, step):
        '''
        #滚动窗口,滚到底
        :param step:操作步骤
        :return:
        '''
        js = "var q=document.documentElement.scrollTop=10000"
        self.driver.execute_script(js)

    @shot
    def switch_to_frame(self, step, xpath):
        '''
        #切换到iframe里边
        :param step:操作步骤
        :param xpath: xpath
        :return:
        '''
        element = self.local_element(xpath)
        self.driver.switch_to.frame(element)

    @shot
    def switch_to_content(self, step):
        '''
        #切出iframe,回到默认页面
        :param step:操作步骤
        :return:
        '''
        self.driver.switch_to.default_content()

    @shot
    def select_by_index(self, step, xpath, index):
        '''
        #操作select下拉框,通过下标选择
        :param step:操作步骤
        :param xpath:xpath
        :param index:下标
        :return:
        '''
        element = self.local_element(xpath)
        Select(element).select_by_index(index)

    @shot
    def select_by_value(self, step, xpath, value):
        '''
        #操作select下拉框,通过value值选择
        :param step: 操作步骤
        :param xpath: xpath
        :param value: value值
        :return:
        '''
        element = self.local_element(xpath)
        Select(element).select_by_value(value)

    @shot
    def select_by_visible_text(self, step, xpath, text):
        '''
        #操作select下拉框,通过可视文本值选择
        :param step:操作步骤
        :param xpath:xpath
        :param text:可视文本
        :return:
        '''
        element = self.local_element(xpath)
        Select(element).select_by_visible_text(text)

    @shot
    def switch_to_windows_by_title(self, step, title):
        '''
        #切换到名字为title的窗口
        :param step: 操作步骤
        :param title: 窗口标题
        :return: 返回值:当前窗口的句柄
        '''
        current = self.driver.current_window_handle
        handles = self.driver.window_handles
        for handle in handles:
            self.driver.switch_to_window(handle)
            if (self.driver.title.__contains__(title)):
                break
        return current

    @shot
    def switch_to_alter_accept(self, step):
        '''
        #窗口切换至弹窗并确认
        :param step:操作步骤
        :return:
        '''
        try:
            WebDriverWait(self.driver, 5, 0.5).until(EC.alert_is_present)
        except BaseException:
            print('弹框不存在')
            raise
        self.driver.switch_to_alert()
        self.driver.switch_to_alert().accept()

    @shot
    def switch_to_alter_dismiss(self, step):
        '''
        #窗口切换至弹窗并取消
        :param step:操作步骤
        :return:
        '''
        try:
            WebDriverWait(self.driver, 5, 0.5).until(EC.alert_is_present)
        except BaseException:
            print('弹框不存在')
            raise
        self.driver.switch_to_alert()
        self.driver.switch_to_alert().dismiss()

    @shot
    def switch_to_alter_send_keys(self, step, text):
        '''
        #窗口切换至弹窗输入内容并确定
        :param step: 操作步骤
        :param text: 输入的文本
        :return:
        '''

        try:
            WebDriverWait(self.driver, 5, 0.5).until(EC.alert_is_present)
        except BaseException:
            print('弹框不存在')
            raise
        self.driver.switch_to_alert()
        alert = self.driver.switch_to_alert()
        alert.send_keys(text)
        alert.accept()

    @shot
    def forward(self, step):
        '''
        #导航栏操作,前进
        :param step: 操作步骤
        :return:
        '''
        self.driver.forward()

    @shot
    def back(self, step):
        '''
        #导航栏操作,后退
        :param step:
        :return:
        '''
        self.driver.back()

    @shot
    def refresh(self, step):
        '''
        #导航栏操作,刷新
        :param step: 操作步骤
        :return:
        '''
        self.driver.refresh()

    def execute_script(self, js):
        self.driver.execute_script(js)

    def double_to_single_mark(self, s):
        return s.replace('"', '\'')

    @shot
    def update_attribute_by_xpath(
            self,
            step,
            xpath,
            attribute_name,
            attribute_value):
        '''
        #通过xpath根据修改html标签属性的值
        :param step: 操作步骤
        :param xpath: xpath
        :param attribute_name:属性名
        :param attribute_value: 属性值
        :return:
        '''
        try:
            self.local_element(xpath)
            js = "var xpath = \"" + self.double_to_single_mark(
                xpath) + "\";var element = document.evaluate(xpath,document,null,XPathResult.ANY_TYPE,null).iterateNext();element.setAttribute(\"" + attribute_name + "\",\"" + attribute_value + "\");"
            self.execute_script(js)
        except BaseException:
            print("修改属性值失败,属性名:" + attribute_name + " 属性值:" + attribute_value)
            raise

    @shot
    def remove_attribute_by_xpath(self, step, xpath, attribute_name):
        '''
        #通过xpath删除html标签属性
        :param step:操作步骤
        :param xpath:xpath
        :param attribute_name:属性名
        :return:
        '''
        try:
            self.local_element(xpath)
            js = "var xpath = \"" + self.double_to_single_mark(
                xpath) + "\";var element = document.evaluate(xpath,document,null,XPathResult.ANY_TYPE,null).iterateNext();element.removeAttribute(\"" + attribute_name + "\");"
            self.execute_script(js)
        except BaseException:
            print("修改属性值失败,属性名:" + attribute_name)
            raise

    @shot
    def move_to_element(self, step, xpath):
        '''
        #窗口滚动到指定的元素
        :param step: 操作步骤
        :param xpath: xpath
        :return:
        '''
        ActionChains(
            self.driver).move_to_element(
            self.local_element(xpath)).perform()

    @shot
    def get_text(self, step, xpath):
        '''
        #获取元素的展示文本
        :param step:操作步骤
        :param xpath:xpath
        :return:页面元素的展示文本
        '''

        element = self.local_element(xpath)

        return element.text

    @shot
    def DOWN(self, step, Keys):
        '''
        #导航栏操作,刷新
        :param step: 操作步骤
        :return:
        '''
        self.driver.find_element_by_id('kw').send_keys(Keys.DOWN)

    @shot
    def ENTER(self, step, Keys):
        '''
        #键盘操作, 回车
        :param Keys:
        :return:
        '''
        self.driver.find_element_by_id('kw').send_keys(Keys.ENTER)
        
    @shot
    def upload_files(self, step, Xpath, file_path):
        '''
        #xpath 定位 输入文件路径 上传文件
        :param Keys:操作步骤,xpath定位 输入文件路径
        :return:
        '''
        self.driver.find_element_by_xpath(Xpath).send_keys(file_path)

conftest.py

该文件主要作用是执行用例执行之前和用例执行之后的操作,类似于jmeter中的前置处理器和后置处理器,起到一个封装启动浏览器的一个操作.

@pytest.fixture(scope='session')
def driver():
    driver = webdriver.Chrome('D:/softwaredata/pycharm/ui_test/chromedriver/chromedriver.exe')
    driver.maximize_window()
    driver.implicitly_wait(8)
    yield driver
    driver.quit()

调用baseui.py文件,编写业务代码

from Common.baseui import baseUI

'''
用例调用conftest.py的driver方法,先执行yield 之前的代码,用例执行完成之后,再执行yield后面的代码
执行步骤为:
1.请参照上面的代码依次观看
1.1.获取本地的chromedriver驱动
1.2.最大化浏览器
1.3.设置隐性等待时间

2.执行测试用例里面的代码,参照test_input1方法依次观看
2.1.调用并且实例化baseUI
2.2.输入URL
2.3.定位元素://input[@name='t1'],操作元素输入:果芽软件

3.参照driver方法yield 之后的代码
3.1.最后执行driver.quit() 关闭浏览器
'''
def test_input1(driver):
    base = baseUI(driver)
    # 输入URL
    driver.get('测试的URL')  
    # 第一个参数是操作步骤名称 第二个参数是xpath 第三个参数是输入框输入的值
    base.send_keys("纯输入框", "//input[@name='t1']", "果芽软件")  

第二种封装,先把selenium的内置方法用装饰器装饰起来,然后再利用conftest.py前置操作后置操作调用装饰好的BaseUi类,话不多说,请看代码

二次封装好的baseui工具类

import time
import allure
from selenium import webdriver


def shot(func):
    def function(*args, **kwargs):
        allure.attach(
            args[0].driver.get_screenshot_as_png(),
            '操作之前',
            allure.attachment_type.PNG)
        res = func(*args, **kwargs)
        allure.attach(
            args[0].driver.get_screenshot_as_png(),
            '操作之后',
            allure.attachment_type.PNG)
        return res

    return function

'''
上面的baseui类谁实例化谁调用,下面的baseui直接在init方法里面打开driver驱动,实例化driver之后,
后续的调用者就不用再实例化操作 直接调用conftest里面的base方法即可
'''
class BaseUi:
    def __init__(self):
        driver = webdriver.Chrome(
            'D:/softwaredata/pycharm/ui_test825/chrom_driver/chromedriver.exe')
        driver.maximize_window()
        driver.implicitly_wait(10)
        self.driver = driver

    @shot
    def get(self, url):
        self.driver.get(url)
        time.sleep(1)

    @shot
    def click(self, step, xpath):
        element = self.driver.find_element_by_xpath(xpath)
        element.click()
        time.sleep(1)

    @shot
    def send_keys(self, step, xpath, value):
        ele = self.driver.find_element_by_xpath(xpath)
        ele.clear()
        ele.send_keys(value)

conftest.py公共方法

import pytest
from base_ui import BaseUi


# 公共方法
@pytest.fixture(scope='session')
def base():
    # 前置操作,调用baseUi(),实例化操作
    base = BaseUi()
    yield base
    # 后置操作,关闭浏览器
    base.driver.quit()

编写业务代码

# 编写业务代码,(base)就是调用conftest里面base公共方法 
def test_click(base):
    # 调用base二次封装好的get方法,输入URL
    base.get("测试的URL")
    # 调用base二次封装好的send_keys方法,输入xpath:"//input[@name='t1']" 输入框输入值:"果芽软件"
    base.send_keys("输入纯输入框", "//input[@name='t1']", "果芽软件")



链接:https://www.jianshu.com/p/52c479415b1e

posted @ 2021-08-23 17:28  忧伤恋上了快乐  阅读(284)  评论(0编辑  收藏  举报