├── PageObject
├── __init__.py
└── loginPage.py
├── test_case
├── __init__.py
├── test01_login.py
└── reports
│ └── 测试报告示例.html
├── models
├── __init__.py
├── url.py
├── mail.py
└── osDriver.py
├── __init__.py
├── .gitattributes
├── Browser_Driver
└── __init__.py
├── logs
└── 1603157033.log
├── reports
├── XML测试报告示例.xml
└── 测试报告示例.html
├── run.py
├── README.md
└── LICENSE
/PageObject/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test_case/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/models/__init__.py:
--------------------------------------------------------------------------------
1 | from .osDriver import osSystem
2 | from .url import Url
--------------------------------------------------------------------------------
/models/url.py:
--------------------------------------------------------------------------------
1 | # -*-coding:utf-8-*-
2 | """
3 | 存储项目测试网站的地址
4 | """
5 | class Url:
6 | baseUrl = 'https://www.baidu.com'
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | 更新时间:2020-08-27
3 | 版本说明:
4 | 1、seldom:1.6.0
5 | 2、poium:0.6.3
6 | 3、Python:3.7.4
7 | """
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.md linguist-language=Python
2 | *.js linguist-language=python
3 | *.css linguist-language=python
4 | *.html linguist-language=python
5 |
--------------------------------------------------------------------------------
/Browser_Driver/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | 注意检查 浏览器驱动 是否于本地浏览器版本一致
3 | Chrome浏览器驱动下载地址:http://npm.taobao.org/mirrors/chromedriver/
4 |
5 | geckodriver(Firefox):https://github.com/mozilla/geckodriver/releases
6 |
7 | IEDriverServer(IE):http://selenium-release.storage.googleapis.com/index.html
8 |
9 | operadriver(Opera):https://github.com/operasoftware/operachromiumdriver/releases
10 |
11 | MicrosoftWebDriver(Edge):https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver
12 | """
--------------------------------------------------------------------------------
/models/mail.py:
--------------------------------------------------------------------------------
1 | from seldom import SMTP
2 | import time
3 |
4 | # 配置e-mail信息
5 | # user = 'you@126.com' # 发送者邮件账号
6 | # password = 'DINODMVPZVSBPYKA' # 发送者邮件授权码
7 | # host = 'smtp.126.com' # host路径
8 | # to = 'to@mail.com' # 邮件接收者,如有多个','英文逗号分割
9 | # subject = None
10 |
11 |
12 | def sendMail(user, password, host, to, subject=None):
13 | try:
14 | smtp = SMTP(user=user, password=password, host=host)
15 | time.sleep(3)
16 | smtp.sender(to=to, subject=subject)
17 | except Exception as error:
18 | return error
19 |
--------------------------------------------------------------------------------
/PageObject/loginPage.py:
--------------------------------------------------------------------------------
1 | # -*-coding:utf-8-*-
2 | # 用于登录页元素定位
3 | from models import Url
4 | from poium import Page, Element
5 |
6 |
7 | class login(Page):
8 | """ 项目用户登录、退出定位元素"""
9 | # url
10 | url = Url.baseUrl
11 |
12 | # 示例
13 | search_input_loc = Element(id_='kw')
14 | search_button_loc = Element(id_='su')
15 |
16 | # 操作方法封装
17 | def search_input(self, key):
18 | self.search_input_loc.clear()
19 | self.search_input_loc.send_keys(key)
20 |
21 | def search_button(self):
22 | self.search_button_loc.click()
23 |
--------------------------------------------------------------------------------
/logs/1603157033.log:
--------------------------------------------------------------------------------
1 | [32m2020-10-20 09:23:53 [INFO] 当前操作系统:Mac OS[0m
2 | [32m2020-10-20 09:23:53 [INFO] 正在检查本地ChromeDriver!!![0m
3 | [32m2020-10-20 09:23:53 [INFO] ❎检查不到Chromedriver,正在下载...[0m
4 | [32m2020-10-20 09:23:54 [INFO] 线上最新版本:87.0.4280.20[0m
5 | [32m2020-10-20 09:23:55 [INFO] Mac驱动下载成功!!![0m
6 | [32m2020-10-20 09:23:55 [INFO] 解压成功!!![0m
7 | [32m2020-10-20 09:23:55 [INFO] ChromeDriver驱动压缩包删除成功!!![0m
8 | [32m2020-10-20 09:23:56 [INFO] 当前版本号:87.0.4280.20[0m
9 | [32m2020-10-20 09:23:56 [INFO] 线上最新版本:87.0.4280.20[0m
10 | [32m2020-10-20 09:23:56 [INFO] ✅当前系统Chromedriver已经是最新版本[0m
11 | [32m2020-10-20 09:24:00 [INFO]
12 | _ _
13 | | | | |
14 | ___ ___ | | __| | ___ _ __ ___
15 | / __| / _ \| | / _` | / _ \ | '_ ` _ \
16 | \__ \| __/| || (_| || (_) || | | | | |
17 | |___/ \___||_| \__,_| \___/ |_| |_| |_|
18 | -----------------------------------------
19 | @itest.info
20 | [0m
21 | [32m2020-10-20 09:24:04 [INFO] 👀 assertText: 百度一下.[0m
22 | [32m2020-10-20 09:24:06 [INFO] 👀 assertText: 百度一下.[0m
23 | [32m2020-10-20 09:24:07 [INFO] 👀 assertText: 百度一下.[0m
24 | [32m2020-10-20 09:24:09 [INFO] 👀 assertText: 百度一下.[0m
25 | [32m2020-10-20 09:24:11 [INFO] 👀 assertText: 百度一下.[0m
26 | [32m2020-10-20 09:24:11 [INFO] generated html file: file:////Users/yuanbaolei/work/GitHub/UIautoDemo/reports/2020_10_20_09_24_00_result.html[0m
27 | [31m2020-10-20 09:24:15 [ERROR] ❌ Email failed to send!!(535, b'Error: authentication failed')[0m
28 |
--------------------------------------------------------------------------------
/reports/XML测试报告示例.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
9 |
10 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
27 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/run.py:
--------------------------------------------------------------------------------
1 | """
2 | main方法说明:
3 | path : 指定测试目录或文件,
4 | browser : 指定测试浏览器,默认Chrome,
5 | report : 自定义测试报告的名称,默认格式为2020_04_04_11_55_20_result.html,
6 | title : 指定测试报告标题,
7 | description : 指定测试报告描述,
8 | debug : debug模式,设置为True不生成测试HTML测试,默认为False,
9 | rerun : 设置失败重新运行次数,默认为 0,
10 | save_last_run : 设置只保存最后一次的结果,默认为False,
11 | driver_path : 设置浏览器驱动的绝对路径。要和 browser 设置保持一致;默认,
12 | grid_url : 设置远程节点,selenium Grid doc,
13 | timeout : 设置超时时间,默认10秒,
14 | xmlrunner : 默认False,True生成xml格式的测试报告,html与xml报告二者选一
15 |
16 |
17 | 邮件发送功能:
18 | 引入'from models.mail import sendMail'
19 | user = 'you@126.com' # 发送邮件账号
20 | password = 'ABC123' # 发送邮件密码
21 | host = 'smtp.126.com' # host路径
22 | to = 'receive@mail.com' # 邮件接受者,如有多个','英文逗号分割
23 | sendMail(user, password, host, to)
24 | """
25 |
26 |
27 | import seldom
28 | from seldom import ChromeConfig
29 | from models.mail import sendMail
30 | from Cdriver import cdriver
31 |
32 | # 配置e-mail信息
33 | user = 'you@126.com' # 发送者邮件账号
34 | password = 'DINODMVPZVSBPYKA' # 发送者邮件授权码
35 | host = 'smtp.126.com' # host路径
36 | to = 'to@mail.com' # 邮件接收者,如有多个','英文逗号分割
37 |
38 |
39 | if __name__ == '__main__':
40 | ChromeConfig.headless = False
41 | ChromeConfig.executable_path = cdriver() # 默认根据操作系统自行选择Chromedriver驱动
42 | seldom.main(
43 | path='./test_case/test01_login.py',
44 | browser='chrome',
45 | debug=False,
46 | rerun=0,
47 | timeout=10,
48 | save_last_run=True,
49 | title='自动化测试报告',
50 | description='测试环境:Chrome'
51 | )
52 | """mail邮件发送;关闭注释启用"""
53 | sendMail(user, password, host, to)
--------------------------------------------------------------------------------
/test_case/test01_login.py:
--------------------------------------------------------------------------------
1 | """
2 | 说明:
3 | # 调用的到的 第三方模块:seldom、sys、time
4 | # from seldom import Seldom
5 | # import seldom
6 | # 调用的到的 私有化模块:model/page_object/
7 | """
8 |
9 | import seldom
10 | from seldom import Seldom, ChromeConfig
11 | import os
12 | import sys
13 | sys.path.append(os.pardir)
14 | from models.osDriver import osSystem
15 | from PageObject.loginPage import login
16 |
17 | class test01_login(seldom.TestCase):
18 | def start(self):
19 | self.dr = login(Seldom.driver)
20 | self.dr.get(login.url)
21 | self.max_window()
22 |
23 | def down(self):
24 | self.quit()
25 |
26 | @classmethod
27 | def setUpClass(cls):
28 | cls().start()
29 |
30 | def test01(self):
31 | """测试示例1"""
32 | self.dr.search_input(key='百度一下')
33 | self.dr.search_button()
34 | self.assertText("百度一下")
35 | print('用例说明:test01')
36 |
37 | def test02(self):
38 | """测试示例2"""
39 | self.dr.search_input_loc.clear()
40 | self.dr.search_input_loc.send_keys('百度一下')
41 | self.dr.search_button_loc.click()
42 | self.assertText("百度一下")
43 | print('用例说明:test02')
44 |
45 | def test03(self):
46 | """测试示例3"""
47 | self.dr.search_input(key='百度一下')
48 | self.dr.search_button()
49 | self.assertText("百度一下")
50 | print('用例说明:test03')
51 |
52 | def test04(self):
53 | """测试示例4"""
54 | self.dr.search_input(key='百度一下')
55 | self.dr.search_button()
56 | self.assertText("百度一下")
57 | print('用例说明:test04')
58 |
59 | def test05(self):
60 | """测试示例5"""
61 | self.dr.search_input(key='百度一下')
62 | self.dr.search_button()
63 | self.assertText("百度一下")
64 | print('用例说明:test05')
65 |
66 |
67 | if __name__ == '__main__':
68 | ChromeConfig.headless = False
69 | ChromeConfig.executable_path = osSystem('../') # 默认根据操作系统自行选择Chromedriver驱动
70 | seldom.main(
71 | path='../test_case/test01_login.py',
72 | browser='chrome',
73 | debug=False,
74 | rerun=0,
75 | timeout=10,
76 | save_last_run=True,
77 | title='自动化测试报告',
78 | description='测试环境:Chrome'
79 | )
80 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # UiAutoDemo
2 | >基于seldom 和 poium库的 UI自动化测试框架模板
3 |
4 | #### 简介
5 |
6 | UiAutoDemo是一个下载即可用的UI自动化测试框架,专为公司自动化项目免去搭建自动化脚手架,也极其适合刚入门的自动化测试小白。很多入门小白不知道如何去搭建脚本的基本结构,自动化的框架架构;不用担心!这款框架绝对让您满意!
7 |
8 | ```框架支持邮件发送、HTML测试报告、框架默认含Chrome浏览器驱动```
9 |
10 | #### 特点
11 | + 已经搭建好的```PageObject```设计模式的脚手架。
12 | + 提供[seldom](https://github.com/SeldomQA/seldom/blob/master/docs/seldom_api.md) 与 [poium](https://github.com/SeldomQA/poium/wiki) API编写自动化测试。
13 | + 全局启动浏览器和关闭浏览器,减少浏览器的启动次数。
14 | + 支持测试用例参数化 [parameterized](https://github.com/SeldomQA/seldom/blob/master/docs/parameterized.md)
15 | + 支持用例 失败/错误 重新尝试case
16 | + 支持生成```HTML```测试报告 与 ```XML```测试报告,用例失败/错误自动截图
17 | + 支持```HTML```测试报告邮件发送
18 | + 自动根据当前环境,调用Chrome浏览器驱动
19 |
20 | #### 必看!
21 |
22 | + ```UiAutoDemo```框架使用的是 ```PageObject```设计模式,简称```PO```;不懂什么是PO设计模式,下面有介绍 ↓;
23 | + 使用的编译语言 ```Python>=3.5```;
24 | + 框架使用的是 ```seldom``` 与 ```poium``` 第三方库,往下看有介绍 ↓;
25 | + 本框架自带```Chromedriver```浏览器驱动,自动检测本地操作环境调用该环境相应的Chrome驱动程序,但需要本地浏览器更新到最近版本
26 | + 测试类与测试用例的命名请遵从 ```ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z```
27 | + ```UiAutoDemo```仅兼容```Unittest```框架;请勿使用其他测试框架运行
28 | + 框架内的```Chromedriver```驱动作者会持续更新,也可自行引入路径
29 |
30 | #### 项目架构
31 |
32 | ```
33 | - UiAutoDemo/
34 | - |── test_case/
35 | - |── test_login.py
36 | - |──models/
37 | - |── url.py
38 | - |── mail.py
39 | - |── osDriver.py
40 | - |──PageObject/
41 | - |── loginPage.py
42 | - |── Browser_Driver/
43 | - |── chromedriver84(Mac64)
44 | - |── chromedriver84(win32).exe
45 | - |── reports/
46 | - |—— 年_月_日_时_分_秒_result.html
47 | - |—— 年_月_日_时_分_秒.xml
48 | - └── run.py
49 | ```
50 |
51 | + ```testcase``` 文件夹用于存放页面元素,测试用例,公共元素
52 | + ```- test_login.py``` 编写局部模块的测试用例并执行
53 | + ```models``` 文件夹存放公共元素,如url
54 | + ```- url.py``` 存放测试url路径
55 | + ```- mail.py``` 用于发送邮件
56 | + ```- osDriver.py``` 检查本地操作系统环境,根据本地环境自动选择相应的driver驱动运行项目
57 | + ```PageObject``` 文件夹存放测试过程中需要使用的页面元素
58 | + ```- loginPage.py``` 存放页面元素定位,封装元素实例化
59 | + ```Browser_Driver``` 文件夹存放浏览器驱动
60 | + ```- chromedriver84(Mac64)``` Mac操作系统Chrome驱动
61 | + ```- chromedriver84(win32).exe``` Windows操作系统Chrome驱动
62 | + ```reports``` 文件夹存放项目测试后生成的测试报告
63 | + ```- 年_月_日_时_分_秒_result.html``` HTML测试报告
64 | + ```- 年_月_日_时_分_秒.xml``` XML测试报告
65 | + ```run.py``` 执行所有的测试用例并执行
66 |
67 | #### 依赖库
68 |
69 | + Python3.7.4 >=
70 | + poium0.6.3 >= (pip install poium)
71 | + seldom1.7.0 >= (pip install seldom)
72 |
73 | #### PageObject设计模式
74 |
75 | >PageObject模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,将页面定位和业务操作分开,分离测试对象(元素对象)和测试脚本(用例脚本),提高用例的可维护性。其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在测试页面中可以通过调用页面类来获取页面元素,这样巧妙的避免了当页面元素id或者其他位置变化时,需要改测试页面代码的情况。 当页面元素id变化时,只需要更改测试页Class中页面的属性即可。
76 |
77 |
78 |
79 | #### UiAutoDemo框架模块
80 | ```框架内的每个py文件都有注解;请使用者仔细阅读```
81 |
82 | 1、此框架仅根据PageObject设计模式搭建的基础框架
83 |
84 | 2、封装一些便于运行项目的模块
85 |
86 | 3、Chromedriver驱动调用```from models import osSystem```
87 |
88 | 4、运行项目
89 |
90 |
91 | 
92 |
93 | 5、查看报告
94 | 可以到```reports```查看测试报告
95 |
96 | 
97 |
98 |
99 | #### seldom文档
100 | 请阅读下面的文档,帮助你快速学习了解Seldom。
101 |
102 | * [seldom安装](https://github.com/SeldomQA/seldom/blob/master/docs/install.md)
103 |
104 | * [seldom创建项目](https://github.com/SeldomQA/seldom/blob/master/docs/create_project.md)
105 |
106 | * [浏览器&驱动](https://github.com/SeldomQA/seldom/blob/master/docs/driver.md)
107 |
108 | * [运行测试](https://github.com/SeldomQA/seldom/blob/master/docs/run_test.md)
109 |
110 | * [main()方法](https://github.com/SeldomQA/seldom/blob/master/docs/main.md)
111 |
112 | * [生成测试报告](https://github.com/SeldomQA/seldom/blob/master/docs/reports.md)
113 |
114 | * [seldom 元素定位](https://github.com/SeldomQA/seldom/blob/master/docs/find_element.md)
115 |
116 | * [seldom API](https://github.com/SeldomQA/seldom/blob/master/docs/seldom_api.md)
117 |
118 | * [keys键盘操作](https://github.com/SeldomQA/seldom/blob/master/docs/keys.md)
119 |
120 | * [seldom 断言](https://github.com/SeldomQA/seldom/blob/master/docs/assert.md)
121 |
122 | * [用例失败重跑&自动截图](https://github.com/SeldomQA/seldom/blob/master/docs/rerun_screenshot.md)
123 |
124 | * [数据驱动最佳实践](https://github.com/SeldomQA/seldom/blob/master/docs/parameterized.md)
125 |
126 | * [实现Page Objects设计模式](https://github.com/SeldomQA/seldom/blob/master/docs/poium.md)
127 |
128 | * [生成测试数据](https://github.com/SeldomQA/seldom/blob/master/docs/testdata.md)
129 |
130 | * [跳过测试用例](https://github.com/SeldomQA/seldom/blob/master/docs/skip.md)
131 |
132 | * [发邮件功能](https://github.com/SeldomQA/seldom/blob/master/docs/send_mail.md)
133 |
134 | * [test fixture](https://github.com/SeldomQA/seldom/blob/master/docs/setupclass.md)
135 |
136 | #### poium文档
137 |
138 | * [介绍](https://github.com/SeldomQA/poium/blob/master/README.md)
139 | * [HOME](https://github.com/SeldomQA/poium/wiki)
140 | * [PageSelect](https://github.com/SeldomQA/poium/wiki/PageSelect)
141 | * [PageWait](https://github.com/SeldomQA/poium/wiki/PageWait)
142 |
143 | #### 写到最后
144 |
145 | 1.此项目仅是一个自动化测试项目的脚手架,并不是Python第三方库
146 |
147 | 2.对selenium有一定的基础底子,能够很快用起来;纯小白也没关系,仔细阅读[seldom](https://github.com/SeldomQA/seldom/blob/master/docs/seldom_api.md) 与 [poium](https://github.com/SeldomQA/poium/wiki)文档即可
148 |
149 | 3.后期会不断添加一些新奇功能便于测试项目的工作
150 |
151 | #### 交流
152 |
153 | QQ群:948994709
154 |
--------------------------------------------------------------------------------
/models/osDriver.py:
--------------------------------------------------------------------------------
1 | import re
2 | import os
3 | import zipfile
4 | import platform
5 | import requests
6 | from seldom.logging import log
7 |
8 | """
9 | # 判断当前操作系统环境;以此来自动选择不同浏览器环境的驱动
10 | """
11 |
12 | class automatic(object):
13 | def __init__(self):
14 | self.url = 'http://npm.taobao.org/mirrors/chromedriver/'
15 |
16 | # 获取线上最新版本号与版本时间
17 | def get_latest_version(self):
18 | rep = requests.get(self.url, timeout=30).text
19 | time_list = []
20 | time_version_dict = {}
21 | result = re.compile(r'\d.*?/.*?Z').findall(rep)
22 | for x in result:
23 | time = x[-24:-1]
24 | version = re.compile(r'.*?/').findall(x)[0]
25 | time_version_dict[time] = version
26 | time_list.append(time)
27 | latest_version = time_version_dict[max(time_list)][:-1] # 获取浏览器版本号
28 | log.info('线上最新版本:'+str(latest_version))
29 | return latest_version
30 |
31 | # 下载Mac系统下的Chromedriver
32 | def mac_download_driver(self, path=''):
33 | latest_version = automatic().get_latest_version()
34 | mac_driver_url = self.url + latest_version + '/chromedriver_mac64.zip'
35 | file = requests.get(mac_driver_url, timeout=60)
36 | with open(path + r'Browser_Driver/chromedriver.zip', 'wb') as zip_file:
37 | zip_file.write(file.content)
38 | log.info('Mac驱动下载成功!!!')
39 |
40 | # 下载Windows系统下的Chromedriver
41 | def win_download_driver(self, path=''):
42 | latest_version = automatic().get_latest_version()
43 | win_driver_url = self.url + latest_version + '/chromedriver_win32.zip'
44 | file = requests.get(win_driver_url, timeout=60)
45 | with open(path + r'Browser_Driver/chromedriver.zip', 'wb') as zip_file:
46 | zip_file.write(file.content)
47 | log.info('Windows驱动下载成功!!!')
48 |
49 | # 解压缩包
50 | def Unpack_driver(self, path=''):
51 | file = zipfile.ZipFile(path + r'Browser_Driver/chromedriver.zip', 'r')
52 | for files in file.namelist():
53 | file.extract(files, path + r'Browser_Driver')
54 | log.info('解压成功!!!')
55 | file.close()
56 | os.remove(path + r'Browser_Driver/chromedriver.zip')
57 | log.info('ChromeDriver驱动压缩包删除成功!!!')
58 |
59 | # Mac系统下的本地与线上版本对比
60 | def Contrast_mac(self, path=''):
61 | try:
62 | log.info('正在检查本地ChromeDriver!!!')
63 | r = os.path.abspath(path + r'Browser_Driver/chromedriver')
64 | os.popen('chmod +x '+r)
65 | version = os.popen(r + r' --version').read()
66 | version = version.split(' ')[1]
67 | log.info("当前版本号:"+str(version))
68 | except Exception as error:
69 | error
70 | log.info('❎检查不到Chromedriver,正在下载...')
71 | automatic().mac_download_driver(path=path)
72 | automatic().Unpack_driver(path=path)
73 | r = os.path.abspath(path + r'Browser_Driver/chromedriver')
74 | os.popen('chmod +x ' + r)
75 | version = os.popen(r + r' --version').read()
76 | version = version.split(' ')[1]
77 | log.info("当前版本号:"+str(version))
78 | if version == automatic().get_latest_version():
79 | log.info('✅当前系统Chromedriver已经是最新版本')
80 | else:
81 | log.info('当前系统Chromedriver不是最新版本,需要更新!!! 请等待!!!')
82 | automatic().mac_download_driver(path=path)
83 | automatic().Unpack_driver(path=path)
84 |
85 | # Windows系统下的本地与线上版本对比
86 | def Contrast_win(self, path=''):
87 | try:
88 | log.info('正在检查本地ChromeDriver!!!')
89 | r = os.path.abspath(path + r'Browser_Driver/chromedriver.exe')
90 | version = os.popen('"'+r+'"' + r' --version').read()
91 | version = version.split(' ')[1]
92 | log.info("当前版本号:"+str(version))
93 | except Exception as error:
94 | error
95 | log.info('❎检查不到Chromedriver,正在下载...')
96 | automatic().win_download_driver(path=path)
97 | automatic().Unpack_driver(path=path)
98 | r = os.path.abspath(path + r'Browser_Driver/chromedriver.exe')
99 | version = os.popen('"'+r+'"' + r' --version').read()
100 | version = version.split(' ')[1]
101 | log.info("当前版本号:"+str(version))
102 |
103 | if version == automatic().get_latest_version():
104 | log.info('✅当前系统Chromedriver已经是最新版本')
105 | else:
106 | log.info('当前系统Chromedriver不是最新版本,需要更新!!! 请等待!!!')
107 | automatic().win_download_driver(path=path)
108 | automatic().Unpack_driver(path=path)
109 |
110 | def osSystem(path=''):
111 | os_system = platform.system()
112 | driver = automatic()
113 | if os_system == 'Windows':
114 | log.info('当前操作系统:Windows')
115 | driver.Contrast_win(path=path) # 检查对比Windows系统环境下的Chromedriver
116 | pathWin = path + r'Browser_Driver/chromedriver.exe'
117 | return pathWin
118 | elif os_system == 'Darwin' or \
119 | os_system == 'darwin' or \
120 | os_system == 'Mac' or \
121 | os_system == 'mac' or \
122 | os_system == 'OS X':
123 | log.info('当前操作系统:Mac OS')
124 | driver.Contrast_mac(path=path) # 检查对比Mac系统环境下的Chromedriver
125 | pathMac = path + r'Browser_Driver/chromedriver'
126 | return pathMac
127 | else:
128 | log.error("当前操作系统 " + os_system)
129 | raise SystemExit(log.error(' ❌ The current operating system environment is not Windows or Mac, '
130 | 'please confirm the current environment!!'))
131 |
132 |
133 | if __name__ == '__main__':
134 | result = automatic()
135 | osSystem('../')
136 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/reports/测试报告示例.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |