• seleuium 自动测试工具


    seleuium 自动测试工具

    基础操作对象
    import time
    from selenium import webdriver
    from selenium.webdriver.chrome.webdriver import WebDriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions
    from selenium.webdriver.support.wait import WebDriverWait
    
    from pages.Login import Login
    from pages.config import config
    
    
    class BasePage:
        _baseurl = 'https://ipark-sit.bgy.com.cn/welcome'
    
        def __init__(self, driver=None, op=1):
            self._baseurl = config.get("home-page")
            """
            初始化启动浏览器
            :param driver: 解决继承的子类重复初始化打开浏览器问题
            :param op: 0为复用流量器启动driver,1为打开新的浏览器复用旧的cookie
            """
            if driver is None:
                if op == 0:
                    self.driver = self.options_chrome()
                elif op == 1:
                    self.driver = self.cookie_chrome()
            else:
                self.driver: WebDriver = driver
            time.sleep(1)  # 新打开一个页面强制等待3秒
            Login().login(self.driver)  # 将登录后的cookie写进cookie.yml
            # Login().set_login_cookie(self.driver.get_cookies())  # 将登录后的cookie写进cookie.yml
            self.driver.implicitly_wait(10)  # 设置隐式断言10秒
    
        def options_chrome(self):
            """复用浏览器"""
            chrome_options = webdriver.ChromeOptions()
            chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
            self.driver = webdriver.Chrome(options=chrome_options)
            self.driver.get(self._baseurl)
            return self.driver
    
        def cookie_chrome(self):
            """读取cookie复用登录状态"""
            self.driver = webdriver.Chrome()
            self.driver.get(self._baseurl)  # 打开首页
            cookie = Login().get_login_cookie()
            if cookie is not None:
                cookies = self.driver.get_cookies()
                print(cookies)
                for e in cookie:
                    print(e)
                    self.driver.add_cookie(e)  # 将cookie添加到打开的浏览器中
            # self.driver.refresh()  # 刷新浏览器
            return self.driver
    
        def my_locator(self, by, locator=None):
            """
            封装元素为止传参,使可兼容多种传参
            :param by: css,id,xpath,class_name,link_text,partial_link_text,tag_name
            :param locator:
            :return:
            """
            if locator is None:
                by, value = by[0], by[1]
            else:
                by, value = by, locator
    
            if by.upper() == 'CSS':
                by = By.CSS_SELECTOR
            elif by.upper() == 'ID':
                by = By.ID
            elif by.upper() == 'XPATH':
                by = By.XPATH
            elif by.upper() == 'CLASS_NAME':
                by = By.CLASS_NAME
            elif by.upper() == 'LINK_TEXT':
                by = By.LINK_TEXT
            elif by.upper() == 'PARTIAL_LINK_TEXT':
                by = By.PARTIAL_LINK_TEXT
            elif by.upper() == 'TAG_NAME':
                by = By.TAG_NAME
            else:
                by = by
            return by, value
    
        def find_ele(self, by, locator=None):
            """
            查找元素,支持传(By.type, value),也支持传入By.type, value;
            :param by: css,id,xpath,class_name,link_text,partial_link_text,tag_name
            :param locator:
            :return:
            """
            if locator is None:
                by, value = by[0], by[1]
            else:
                by, value = by, locator
    
            if by.upper() == 'CSS':
                by = By.CSS_SELECTOR
            elif by.upper() == 'ID':
                by = By.ID
            elif by.upper() == 'XPATH':
                by = By.XPATH
            elif by.upper() == 'CLASS_NAME':
                by = By.CLASS_NAME
            elif by.upper() == 'LINK_TEXT':
                by = By.LINK_TEXT
            elif by.upper() == 'PARTIAL_LINK_TEXT':
                by = By.PARTIAL_LINK_TEXT
            elif by.upper() == 'TAG_NAME':
                by = By.TAG_NAME
            else:
                by = by
            self.wait_clickable(by, value)
            return self.driver.find_element(by, value)
    
        def find_ele_list(self, by, locator=None):
            """
            查找元素,支持传(By.type, value),也支持传入By.type, value;
            :param by: css,id,xpath,class_name,link_text,partial_link_text,tag_name
            :param locator:
            :return:
            """
            if locator is None:
                by, value = by[0], by[1]
            else:
                by, value = by, locator
    
            if by.upper() == 'CSS':
                by = By.CSS_SELECTOR
            elif by.upper() == 'ID':
                by = By.ID
            elif by.upper() == 'XPATH':
                by = By.XPATH
            elif by.upper() == 'CLASS_NAME':
                by = By.CLASS_NAME
            elif by.upper() == 'LINK_TEXT':
                by = By.LINK_TEXT
            elif by.upper() == 'PARTIAL_LINK_TEXT':
                by = By.PARTIAL_LINK_TEXT
            elif by.upper() == 'TAG_NAME':
                by = By.TAG_NAME
            else:
                by = by
            return self.driver.find_elements(by, value)
    
        def wait_clickable(self, by, locator=None, time=30):
            """
            显式等待
            :param by:css,id,xpath,class_name,link_text,partial_link_text,tag_name
            :param locator: 等待元素可点击为止,这里需要传入元素的locator
            :param time: 等待时间
            :return:
            """
            WebDriverWait(self.driver, time).until(expected_conditions.element_to_be_clickable(self.my_locator(by, locator)))
    
        def wait_visibility(self, by, locator=None, time=30):
            """
            显式等待
            :param by: css,id,xpath,class_name,link_text,partial_link_text,tag_name
            :param locator: 等待元素可见为止,这里需要传入元素的locator
            :param time: 等待时间
            :return:
            """
            WebDriverWait(self.driver, time).until(expected_conditions.visibility_of_element_located(self.my_locator(by, locator)))
    
        def ele_click(self, by, locator=None):
            """
            点击元素,支持传(By.type, value),也支持传入By.type, value;
            :param by: css,id,xpath,class_name,link_text,partial_link_text,tag_name
            :param locator:
            :return:
            """
            self.find_ele(by, locator=locator).click()
    
        @property
        def baseurl(self):
            return self._baseurl
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    登录页处理
    import time
    
    from selenium.webdriver.common.by import By
    
    from pages.OperationYaml import OperationYaml
    from pages.config import config
    
    _COOKIEYMAL = '../file/cookie.yml'  # 用来放登录后获取的cookie
    
    
    class Login:
        def login(self, driver):
            driver.find_element(By.XPATH, "//div[@id='root']/div/div[2]/div[2]/div/img").click()
            time.sleep(1)  # 新打开一个页面强制等待3秒
            username = driver.find_element(By.ID, "j_username")
            username.clear()
            username.send_keys(config.get("username"))
            passwd = driver.find_element(By.ID, "j_password")
            passwd.clear()
            print(config.get("passwd"))
            passwd.send_keys(config.get("passwd"))
            driver.find_element(By.CLASS_NAME, "loginBt").click()
    
        """处理cookie使免登陆"""
    
        def get_login_cookie(self):
            """读取yaml文件,将cookie读取出来"""
            cookie = OperationYaml().get_yaml(_COOKIEYMAL)
            if isinstance(cookie, list):
                cookies_list = cookie
            else:
                cookies_list = self.str_to_list(cookie)
            return cookies_list
    
        def set_login_cookie(self, cookies):
            """往yaml文件中写入cookie"""
            if isinstance(cookies, list):
                cookies_list = cookies
            else:
                cookies_list = self.str_to_list(cookies)
            OperationYaml().set_w_yaml(cookies_list, _COOKIEYMAL)
    
        def str_to_list(self, cookies):
            """将文本的cookie进行处理,返回的是一个列表"""
            if cookies is not None:
                l_list = cookies.split('; ')
                cookies_list = []
                for i in l_list:
                    key, value = i.split('=', 1)
                    cookie = {'domain': '.bgy.com.cn', 'name': key, 'path': '/', 'value': value}
                    cookies_list.append(cookie)
                return cookies_list
            else:
                return None
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    主方法运行
    import logging
    import time
    
    from selenium.webdriver import ActionChains
    from selenium.webdriver.common.by import By
    
    from pages.BasePage import BasePage
    
    
    class Runner:
    
        def __init__(self):
            self.BasePage = BasePage()
            self.driver = self.BasePage.driver
            self.baseurl = self.BasePage.baseurl
    
        def runner(self, data):
            """
            执行步骤
            :param data: dict
            :return:
            """
            # 1.点击我的空间
            # pro_list = self.driver.find_elements_by_css_selector("ant-menu-overflow-item ant-menu-item "
            #                                                      "ant-menu-item-selected ant-menu-item-only-child")
            # 2.依次点击每个项目,然后点击生成
            pro_list = self.driver.find_elements(By.XPATH, "//div[@class='ant-spin-container']/div/div[2]/div")
            pl_idx = 2
            while pl_idx < len(pro_list):
                pl = pro_list[pl_idx]
                pl.click()
                time.sleep(1)
                self.driver.find_element(By.XPATH, "//div[@class='ant-spin-container']/div/div[2]/div[2]/div").click()
                time.sleep(1)
                self.driver.find_elements(By.CLASS_NAME, "ant-menu-item")[1].click()
                time.sleep(2)
                self.driver.find_elements(By.CLASS_NAME, "ant-menu-item")[2].click()
                confirm = self.driver.find_element(By.XPATH, "//div[@class='ant-modal-confirm-btns']/button[2]")
                # 点击不能直接用click,否则没有用
                if confirm:
                    self.driver.execute_script("arguments[0].click();", confirm)
                    # ActionChains(self.driver).move_to_element(confirm).click().perform()  # 使用鼠标点击的方式
                time.sleep(3)
                self.driver.find_elements(By.CLASS_NAME, "ant-menu-item")[3].click()
                time.sleep(1)
                self.driver.find_elements(By.CLASS_NAME, "ant-menu-overflow-item")[0].click()
                time.sleep(2)
                pro_list = self.driver.find_elements(By.XPATH, "//div[@class='ant-spin-container']/div/div[2]/div")
                pl_idx += 1
    
            logging.info("执行完成....")
    
    
    if __name__ == "__main__":
        data = {"action": "click", "by": "xx"}
        Runner().runner(data)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    读取配置
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Date    : 2021-09-06 17:48:59
    # @Author  : wangmian05
    # @Link    : wangmian05@countrygraden.com.cn
    # @Version : $Id$
    import base64
    import os
    import sys
    
    sys.path.append("..")
    
    import logger as log
    
    config = {}
    
    
    def start_with(cont, param):
        cont = cont.lstrip()
        if param in cont and (cont.index(param) == 0 or cont.index(param) == 1):
            return True
        return False
    
    
    env = sys.argv[1] if len(sys.argv) > 1 else None
    service_port = sys.argv[2] if len(sys.argv) > 2 else 0
    
    log.debug("current env:{},service_port:{}", env, service_port)
    
    env_prefix = env if env and len(env) > 0 else "sit"
    
    log.debug("profile:{}", env_prefix)
    current_path = os.path.abspath(__file__)
    
    father_path = os.path.abspath(os.path.dirname(current_path) + os.path.sep + ".")
    
    ph = str(father_path)
    pwd = ph if ph.rindex("keyword") == 0 else ph[0:(ph.index("keyword") + len("keyword"))]
    case_file_path = pwd + "/server-" + env_prefix + ".conf"
    with open(case_file_path, "rb") as fs:
        for f in fs:
            content = f.decode('utf-8').replace("\r", '').replace("\n", '')
            if len(content) == 0 or start_with(content, "#"):
                continue
            ct_idx = content.index("=")
            isp = [content[0:ct_idx], content[ct_idx + 1:]]
            dbc = isp[1]
            if isp[0] == "passwd":
                encrypt_code = base64.decodebytes(dbc[1:len(dbc) - 1].encode("utf-8"))
                isp[1] = "".join((list(encrypt_code.decode())[::-1])[0:len(list(encrypt_code.decode())) - 6])
            config[isp[0]] = isp[1]
    
    if __name__ == "__main__":
        str = "pass.passwd"
        dy = None
        miwen = base64.encodebytes("".join(list(str)[::-1]).encode("utf-8"))
        print(miwen.decode())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    ##### 配置文件

    # server 配置项
    home-page=https://xx.com.cn/welcome/
    username=user
    passwd='ZHdzc2FwZHJvd3NzYXA='
    
    • 1
    • 2
    • 3
    • 4
    必要依赖处理
    async-generator==1.10
    atomicwrites==1.4.0
    attrs==21.3.0
    certifi==2021.10.8
    cffi==1.15.0
    colorama==0.4.4
    cryptography==36.0.1
    et-xmlfile==1.1.0
    h11==0.12.0
    idna==3.3
    iniconfig==1.1.1
    openpyxl==3.0.9
    outcome==1.1.0
    packaging==21.3
    pluggy==1.0.0
    py==1.11.0
    pycparser==2.21
    pyOpenSSL==21.0.0
    pyparsing==3.0.6
    pytest==6.2.5
    PyYAML==6.0
    selenium==4.1.0
    six==1.16.0
    sniffio==1.2.0
    sortedcontainers==2.4.0
    toml==0.10.2
    trio==0.19.0
    trio-websocket==0.9.2
    urllib3==1.26.7
    wsproto==1.0.0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 相关阅读:
    决策树——依据水果特征分类
    线性代数行列式
    pix2pix学习系列(1):预训练模型测试pix2pix
    10分钟让你熟练Python闭包
    mssql(1433端口)介绍
    查看mysql数据库的版本
    github网站打不开,hosts文件配置
    虚拟环境下把python代码打包成exe(小白教程)
    Go语言常用命令详解(二)
    kotlin基础教程:<4>内置函数的使用
  • 原文地址:https://blog.csdn.net/a249040113/article/details/133268900