├── atp-web-open ├── .env ├── .browserslistrc ├── src │ ├── pages │ │ ├── index │ │ │ ├── index.js │ │ │ └── components │ │ │ │ └── PieChart.vue │ │ ├── login │ │ │ └── index.js │ │ ├── error-page-404 │ │ │ ├── index.js │ │ │ └── page.vue │ │ ├── mock │ │ │ └── mock-log │ │ │ │ └── index.vue │ │ ├── qadata │ │ │ └── form-bugDataStatistics │ │ │ │ └── index.vue │ │ └── tools │ │ │ ├── tool-fareIncreaseService │ │ │ └── index.vue │ │ │ └── tool-loanTransferForDongFang │ │ │ └── index.vue │ ├── layout │ │ └── header-aside │ │ │ ├── index.js │ │ │ └── components │ │ │ ├── mixin │ │ │ └── menu.js │ │ │ ├── header-user │ │ │ └── index.vue │ │ │ ├── components │ │ │ ├── menu-item │ │ │ │ └── index.vue │ │ │ └── menu-sub │ │ │ │ └── index.vue │ │ │ ├── menu-header │ │ │ └── index.vue │ │ │ └── contextmenu │ │ │ ├── components │ │ │ └── contentmenuList │ │ │ │ └── index.vue │ │ │ └── index.vue │ ├── assets │ │ └── style │ │ │ ├── theme │ │ │ ├── atp │ │ │ │ ├── index.scss │ │ │ │ └── setting.scss │ │ │ └── register.scss │ │ │ ├── fixed │ │ │ ├── n-progress.scss │ │ │ ├── base.scss │ │ │ └── element.scss │ │ │ ├── unit │ │ │ └── color.scss │ │ │ ├── animate │ │ │ └── vue-transition.scss │ │ │ ├── public.scss │ │ │ └── public-class.scss │ ├── components │ │ ├── d2-page-cover │ │ │ ├── image │ │ │ │ └── darkblue@2x.png │ │ │ └── index.vue │ │ ├── d2-icon │ │ │ ├── font-awesome-4.7.0 │ │ │ │ └── fonts │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ └── index.vue │ │ ├── index.js │ │ ├── d2-container │ │ │ └── components │ │ │ │ ├── d2-container-ghost.vue │ │ │ │ ├── d2-container-full.vue │ │ │ │ ├── d2-container-card.vue │ │ │ │ ├── d2-container-ghost-bs.vue │ │ │ │ ├── d2-container-full-bs.vue │ │ │ │ ├── d2-container-card-bs.vue │ │ │ │ └── mixins │ │ │ │ └── bs.js │ │ └── SvgIcon │ │ │ └── index.vue │ ├── plugin │ │ ├── open │ │ │ └── index.js │ │ ├── error │ │ │ └── index.js │ │ └── d2admin │ │ │ └── index.js │ ├── icons │ │ ├── svg │ │ │ ├── chart.svg │ │ │ ├── size.svg │ │ │ ├── link.svg │ │ │ ├── guide.svg │ │ │ ├── component.svg │ │ │ ├── money.svg │ │ │ ├── drag.svg │ │ │ ├── email.svg │ │ │ ├── guide 2.svg │ │ │ ├── documentation.svg │ │ │ ├── user.svg │ │ │ ├── lock.svg │ │ │ ├── excel.svg │ │ │ ├── example.svg │ │ │ ├── star.svg │ │ │ ├── table.svg │ │ │ ├── password.svg │ │ │ ├── folder_open_directory_category_browse.svg │ │ │ ├── tab.svg │ │ │ ├── message.svg │ │ │ ├── theme.svg │ │ │ ├── peoples.svg │ │ │ ├── nested.svg │ │ │ ├── edit.svg │ │ │ ├── eye.svg │ │ │ ├── clipboard.svg │ │ │ ├── list.svg │ │ │ ├── icon.svg │ │ │ ├── international.svg │ │ │ ├── catalog.svg │ │ │ ├── wechat.svg │ │ │ ├── people.svg │ │ │ ├── language.svg │ │ │ ├── 404.svg │ │ │ ├── zip.svg │ │ │ ├── bug.svg │ │ │ ├── tree.svg │ │ │ ├── shopping.svg │ │ │ ├── dashboard.svg │ │ │ └── form.svg │ │ └── index.js │ ├── menu │ │ ├── modules │ │ │ ├── home.js │ │ │ ├── monitor.js │ │ │ ├── mock.js │ │ │ ├── sys-manage.js │ │ │ ├── tools-df.js │ │ │ ├── qadata.js │ │ │ ├── tools.js │ │ │ └── autotest-manage.js │ │ └── index.js │ ├── store │ │ ├── index.js │ │ └── modules │ │ │ └── d2admin │ │ │ ├── modules │ │ │ ├── gray.js │ │ │ ├── ua.js │ │ │ ├── interfaces.js │ │ │ ├── testreport.js │ │ │ ├── user.js │ │ │ ├── transition.js │ │ │ ├── fulllinecase.js │ │ │ ├── theme.js │ │ │ └── menu.js │ │ │ └── index.js │ ├── api │ │ ├── tools │ │ │ ├── tool-sendMQ │ │ │ │ └── index.js │ │ │ ├── tool-dataClean │ │ │ │ └── index.js │ │ │ ├── tool-smsCodeQuery │ │ │ │ └── index.js │ │ │ ├── tool-uaaLogDecrypt │ │ │ │ └── index.js │ │ │ ├── tool-creditAuditQuery │ │ │ │ └── index.js │ │ │ ├── tool-loanTransferForDongFang │ │ │ │ └── index.js │ │ │ ├── integration-greenChannelSet │ │ │ │ └── index.js │ │ │ ├── tool-batchGenerateCardNo │ │ │ │ └── index.js │ │ │ ├── tool-loanDateToOverDueForDongFang │ │ │ │ └── index.js │ │ │ ├── tool-creditWhiteList │ │ │ │ └── index.js │ │ │ ├── tool-loanTransfer │ │ │ │ └── index.js │ │ │ ├── tool-updateLogisticsInfo │ │ │ │ └── index.js │ │ │ ├── integration-failReasonSet │ │ │ │ └── index.js │ │ │ ├── tool-loanDataCalculate │ │ │ │ └── index.js │ │ │ ├── tool-setMatchFund │ │ │ │ └── index.js │ │ │ ├── tool-loanDateToOverDue │ │ │ │ └── index.js │ │ │ └── tool-fareIncreaseService │ │ │ │ └── index.js │ │ ├── home │ │ │ └── index.js │ │ ├── mock │ │ │ ├── mock-log │ │ │ │ └── index.js │ │ │ └── mock-config │ │ │ │ ├── interface │ │ │ │ └── index.js │ │ │ │ ├── project │ │ │ │ └── index.js │ │ │ │ └── scene │ │ │ │ └── index.js │ │ ├── qadata │ │ │ ├── form-autoTestData │ │ │ │ └── index.js │ │ │ ├── form-batchRunData │ │ │ │ └── index.js │ │ │ └── chart-successRateCount │ │ │ │ └── index.js │ │ ├── autotest │ │ │ ├── manage │ │ │ │ ├── resource-apiManage │ │ │ │ │ ├── stat │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── project │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── system │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── api │ │ │ │ │ │ └── index.js │ │ │ │ │ └── company │ │ │ │ │ │ └── index.js │ │ │ │ ├── report-testReport │ │ │ │ │ └── index.js │ │ │ │ ├── testcase-apiManage │ │ │ │ │ ├── run │ │ │ │ │ │ └── index.js │ │ │ │ │ └── support │ │ │ │ │ │ └── index.js │ │ │ │ ├── dataAnalysis-reuseRate │ │ │ │ │ └── index.js │ │ │ │ ├── case-report │ │ │ │ │ └── index.js │ │ │ │ ├── testcase-run │ │ │ │ │ └── index.js │ │ │ │ ├── dataAnalysis-regressionResult │ │ │ │ │ └── index.js │ │ │ │ ├── resource-envManage │ │ │ │ │ └── index.js │ │ │ │ ├── fullLineCase │ │ │ │ │ └── produceLine-config │ │ │ │ │ │ └── index.js │ │ │ │ ├── testcase-testCaseConfig │ │ │ │ │ ├── testplan │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── testsuite │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── pageobject │ │ │ │ │ │ └── index.js │ │ │ │ │ └── module │ │ │ │ │ │ └── index.js │ │ │ │ ├── resource-publicVariable │ │ │ │ │ └── index.js │ │ │ │ ├── testTask-manualConfig │ │ │ │ │ └── index.js │ │ │ │ └── testTask-regressionTest │ │ │ │ │ └── index.js │ │ │ └── real-time-log │ │ │ │ └── index.js │ │ ├── sys │ │ │ ├── http │ │ │ │ └── index.js │ │ │ ├── login │ │ │ │ └── index.js │ │ │ └── user │ │ │ │ └── index.js │ │ └── monitor │ │ │ └── businessStatus │ │ │ └── index.js │ ├── App.vue │ ├── libs │ │ ├── db.js │ │ ├── util.js │ │ └── util.cookies.js │ ├── config │ │ └── mqtt.js │ ├── setting.js │ ├── main.js │ └── router │ │ └── index.js ├── babel.config.js ├── public │ ├── icon.ico │ ├── image │ │ ├── theme │ │ │ └── atp │ │ │ │ ├── error │ │ │ │ └── 404.png │ │ │ │ ├── logo │ │ │ │ ├── all.png │ │ │ │ └── home.jpg │ │ │ │ └── login │ │ │ │ └── background.png │ │ └── testtools │ │ │ └── qrcode │ │ │ └── 么么推手生产体验版本.png │ └── index.html ├── postcss.config.js ├── .eslintignore ├── .env.test ├── .env.master ├── .gitignore ├── README.md └── package.json ├── atp-auto-core-open ├── atp │ ├── __init__.py │ ├── engine │ │ ├── __init__.py │ │ ├── return_code_desc.py │ │ ├── exceptions.py │ │ └── code_to_desc.py │ ├── api │ │ ├── __init__.py │ │ ├── tmp │ │ │ └── __init__.py │ │ ├── md5.py │ │ ├── get_log_content.py │ │ ├── git_api.py │ │ ├── comm_log.py │ │ ├── pandas_manager.py │ │ ├── ssh_executor.py │ │ ├── send_email.py │ │ └── safe_file_handler.py │ ├── config │ │ ├── __init__.py │ │ ├── load_config.py │ │ ├── dev.py │ │ └── aliuat.py │ ├── httprunner │ │ ├── __init__.py │ │ ├── __about__.py │ │ ├── templates │ │ │ └── locustfile_template │ │ ├── exceptions.py │ │ └── compat.py │ ├── logs │ │ ├── __init__.py │ │ └── run_case_logs │ │ │ └── __init__.py │ ├── models │ │ └── __init__.py │ ├── utils │ │ ├── __init__.py │ │ ├── temp_code.py │ │ ├── map_functions.py │ │ ├── cache_data.py │ │ ├── background_log_thread.py │ │ └── get_content_from_log.py │ ├── env.py │ └── views │ │ ├── run_ui.py │ │ ├── __init__.py │ │ ├── ui_page.py │ │ └── tag.py ├── run_celery.py ├── .gitignore ├── flower_config.py ├── run_server.py ├── atp_auto_init_data.sql ├── supervisor │ ├── flask_atp_socket.conf.not_use │ ├── flask_atp_auto.conf │ ├── flask_atp_celery_monitor.conf │ ├── flask_atp_celery_task.conf │ ├── flask_atp_celery_task_sit.conf │ ├── flask_atp_celery_default.conf │ └── flask_atp_celery_default_sit.conf ├── README.md ├── gunicorn │ ├── gunicorn_config.py │ └── gunicorn_config_for_socket.py └── requirements.txt ├── images ├── atp2.png ├── 工程结构.png ├── 模块结构.png ├── 用例配置.jpg ├── 前后端架构.jpg ├── 接口用例列表.jpg ├── 在线执行实时日志.jpg ├── 接口用例树形管理.jpg ├── 用例执行流程图.jpg └── 用例管理结构图.jpg └── README.md /atp-web-open/.env: -------------------------------------------------------------------------------- 1 | # 页面标题 2 | VUE_APP_TITLE = Auror 3 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/__init__.py: -------------------------------------------------------------------------------- 1 | # # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/engine/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/tmp/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/config/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /atp-web-open/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /images/atp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/atp2.png -------------------------------------------------------------------------------- /images/工程结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/工程结构.png -------------------------------------------------------------------------------- /images/模块结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/模块结构.png -------------------------------------------------------------------------------- /images/用例配置.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/用例配置.jpg -------------------------------------------------------------------------------- /images/前后端架构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/前后端架构.jpg -------------------------------------------------------------------------------- /images/接口用例列表.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/接口用例列表.jpg -------------------------------------------------------------------------------- /images/在线执行实时日志.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/在线执行实时日志.jpg -------------------------------------------------------------------------------- /images/接口用例树形管理.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/接口用例树形管理.jpg -------------------------------------------------------------------------------- /images/用例执行流程图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/用例执行流程图.jpg -------------------------------------------------------------------------------- /images/用例管理结构图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/images/用例管理结构图.jpg -------------------------------------------------------------------------------- /atp-web-open/src/pages/index/index.js: -------------------------------------------------------------------------------- 1 | import page from './page' 2 | 3 | export default page 4 | -------------------------------------------------------------------------------- /atp-web-open/src/pages/login/index.js: -------------------------------------------------------------------------------- 1 | import page from './page' 2 | 3 | export default page 4 | -------------------------------------------------------------------------------- /atp-web-open/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /atp-web-open/public/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/public/icon.ico -------------------------------------------------------------------------------- /atp-web-open/src/pages/error-page-404/index.js: -------------------------------------------------------------------------------- 1 | import page from './page' 2 | 3 | export default page 4 | -------------------------------------------------------------------------------- /atp-web-open/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/index.js: -------------------------------------------------------------------------------- 1 | import layout from './layout' 2 | 3 | export default layout 4 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/theme/atp/index.scss: -------------------------------------------------------------------------------- 1 | @import './setting.scss'; 2 | @import '../theme.scss'; 3 | 4 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/httprunner/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | from atp.httprunner.api import HttpRunner, LocustRunner 4 | -------------------------------------------------------------------------------- /atp-web-open/public/image/theme/atp/error/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/public/image/theme/atp/error/404.png -------------------------------------------------------------------------------- /atp-web-open/public/image/theme/atp/logo/all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/public/image/theme/atp/logo/all.png -------------------------------------------------------------------------------- /atp-web-open/public/image/theme/atp/logo/home.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/public/image/theme/atp/logo/home.jpg -------------------------------------------------------------------------------- /atp-auto-core-open/atp/logs/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | """ 4 | File Name: `__init__.py`.py 5 | Version: 6 | Description: 7 | 8 | """ 9 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/models/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | """ 4 | File Name: `__init__.py`.py 5 | Version: 6 | Description: 7 | 8 | """ 9 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | """ 4 | File Name: `__init__.py`.py 5 | Version: 6 | Description: 7 | 8 | """ 9 | -------------------------------------------------------------------------------- /atp-web-open/public/image/testtools/qrcode/么么推手生产体验版本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/public/image/testtools/qrcode/么么推手生产体验版本.png -------------------------------------------------------------------------------- /atp-web-open/public/image/theme/atp/login/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/public/image/theme/atp/login/background.png -------------------------------------------------------------------------------- /atp-auto-core-open/atp/logs/run_case_logs/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | """ 4 | File Name: `__init__.py`.py 5 | Version: 6 | Description: 7 | 8 | """ 9 | -------------------------------------------------------------------------------- /atp-web-open/.eslintignore: -------------------------------------------------------------------------------- 1 | # 忽略目录 2 | build/ 3 | tests/ 4 | node_modules/ 5 | 6 | # node 覆盖率文件 7 | coverage/ 8 | 9 | # 忽略文件 10 | **/*-min.js 11 | **/*.min.js 12 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-page-cover/image/darkblue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/src/components/d2-page-cover/image/darkblue@2x.png -------------------------------------------------------------------------------- /atp-web-open/src/plugin/open/index.js: -------------------------------------------------------------------------------- 1 | import util from '@/libs/util' 2 | 3 | export default { 4 | install(Vue, options) { 5 | Vue.prototype.$open = util.open 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /atp-web-open/.env.test: -------------------------------------------------------------------------------- 1 | # 网络请求公用地址 2 | NODE_ENV = "production" 3 | VUE_APP_API="//XX.XX.XX.XX:8899" 4 | VUE_APP_CURRENTMODE = 'test' 5 | VUE_APP_V_HOST = "atp_dev" 6 | VUE_APP_Version=2.0 7 | 8 | 9 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/theme/register.scss: -------------------------------------------------------------------------------- 1 | @import '~@/assets/style/public.scss'; 2 | @import '~@/assets/style/theme/theme-base.scss'; 3 | 4 | @import '~@/assets/style/theme/atp/index.scss'; 5 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /atp-web-open/.env.master: -------------------------------------------------------------------------------- 1 | # 网络请求公用地址 2 | NODE_ENV = "production" 3 | VUE_APP_API="//XX.XX.XX.XX:8899" 4 | VUE_APP_CURRENTMODE = 'master' 5 | VUE_APP_V_HOST = "atp_uat" 6 | VUE_APP_Version=2.0 7 | 8 | 9 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/chart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/home.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '', 3 | title: '首页', 4 | icon: 'home', 5 | children: (pre => [ 6 | { path: `${pre}index`, title: '首页', icon: 'home' } 7 | ])('/') 8 | } 9 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooqitech/ATP/HEAD/atp-web-open/src/components/d2-icon/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/fixed/n-progress.scss: -------------------------------------------------------------------------------- 1 | #nprogress { 2 | .bar { 3 | background: $color-danger !important; 4 | } 5 | .peg { 6 | box-shadow: 0 0 10px $color-danger, 0 0 5px $color-danger !important; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/size.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/engine/return_code_desc.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | CODE_DESC_MAP = { 4 | '000': '', 5 | '100': '入参校验失败', 6 | '110': '用户未登录', 7 | '120': 'Sorry, 当前用户没有此项操作权限', 8 | '999': 'system error', 9 | } 10 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/monitor.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '/monitor', 3 | title: '统一监控', 4 | icon: 'heartbeat', 5 | children: (pre => [ 6 | { path: `${pre}businessStatus`, title: '业务应用在线状态', icon: 'edit' } 7 | ])('/monitor/') 8 | } 9 | -------------------------------------------------------------------------------- /atp-web-open/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | import d2admin from './modules/d2admin' 5 | 6 | Vue.use(Vuex) 7 | 8 | export default new Vuex.Store({ 9 | modules: { 10 | d2admin 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /atp-auto-core-open/run_celery.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | from atp.app import create_app 4 | from atp.extensions import celery 5 | 6 | app = create_app() 7 | 8 | if __name__ == '__main__': 9 | with app.app_context(): 10 | celery.start() 11 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-sendMQ/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取短信验证码接口 4 | */ 5 | 6 | export function sendMQ(data) { 7 | return request({ 8 | url: '/atp/qa/sendMQ', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-dataClean/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 清理测试数据接口 4 | */ 5 | 6 | export function clearData(data) { 7 | return request({ 8 | url: '/atp/qa/clearData', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-smsCodeQuery/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取短信验证码接口 4 | */ 5 | 6 | export function getSms(data) { 7 | return request({ 8 | url: '/atp/qa/getSms', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /atp-web-open/src/api/home/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取自动化用例统计数据 4 | */ 5 | 6 | export function testcaseSummary(data) { 7 | return request({ 8 | url: '/atp/auto/stat/testcaseSummary', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-uaaLogDecrypt/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取短信验证码接口 4 | */ 5 | 6 | export function uaaLogDecrypt(data) { 7 | return request({ 8 | url: '/atp/qa/uaaLogDecrypt', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/api/mock/mock-log/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 获取mock日志 5 | */ 6 | 7 | export function getMockHistory(data) { 8 | return request({ 9 | url: '/atp/mock/support/getMockHistory', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-creditAuditQuery/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取短信验证码接口 4 | */ 5 | 6 | export function crediAuditQuery(data) { 7 | return request({ 8 | url: '/atp/qa/crediAuditQuery', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-loanTransferForDongFang/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 一键放款接口 4 | */ 5 | 6 | export function executeLoan(data) { 7 | return request({ 8 | url: '/atp/qa/executeLoan', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/integration-greenChannelSet/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 设置绿色通道接口 4 | */ 5 | 6 | export function setGreenchannel(data) { 7 | return request({ 8 | url: '/atp/qa/greenChannel', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/components/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import d2Container from './d2-container' 4 | 5 | // 注意 有些组件使用异步加载会有影响 6 | Vue.component('d2-container', d2Container) 7 | Vue.component('d2-page-cover', () => import('./d2-page-cover')) 8 | Vue.component('d2-icon', () => import('./d2-icon')) 9 | -------------------------------------------------------------------------------- /atp-web-open/src/api/qadata/form-autoTestData/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询所有自动化项目详细信息接口 4 | */ 5 | 6 | export function queryAutotestDetails(data) { 7 | return request({ 8 | url: '/atp/qa/queryAutotestDetails', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-batchGenerateCardNo/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 批量生成银行卡号 4 | */ 5 | 6 | export function batchGenerateCardNo(data) { 7 | return request({ 8 | url: '/atp/qa/generateBankCardList', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-auto-core-open/.gitignore: -------------------------------------------------------------------------------- 1 | # 忽略所有pyc的文件 2 | *.pyc 3 | 4 | # 忽略.idea 文件夹 5 | .idea/ 6 | 7 | # 忽略所有的 log 文件 8 | *.log 9 | 10 | # 忽略所有的 JSON 文件, XLS 文件,png 文件 11 | *.json 12 | *.xls 13 | *.png 14 | *.xmind 15 | *.txt 16 | 17 | # 忽略虚拟环境文件夹 18 | venv/ 19 | 20 | # 忽略migration文件夹 21 | migrations/ 22 | 23 | 24 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/resource-apiManage/stat/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 统计接口用例数 5 | */ 6 | 7 | export function getStatistics(data) { 8 | return request({ 9 | url: '/atp/auto/stat/getStatistics', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-loanDateToOverDueForDongFang/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 指定放款时间只生成还款计划 4 | */ 5 | 6 | export function updateLoanPlan(data) { 7 | return request({ 8 | url: '/atp/qa/updateLoanPlanForDongFang', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/mock.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '/mock', 3 | title: 'mock管理', 4 | icon: 'get-pocket', 5 | children: (pre => [ 6 | { path: `${pre}mock-config`, title: 'mock配置', icon: 'edit' }, 7 | { path: `${pre}mock-log`, title: 'mock日志', icon: 'file-text-o' } 8 | ])('/mock/') 9 | } 10 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/SvgIcon' // svg组件 3 | 4 | // register globally 5 | Vue.component('svg-icon', SvgIcon) 6 | const req = require.context('./svg', false, /\.svg$/) 7 | const requireAll = requireContext => requireContext.keys().map(requireContext) 8 | requireAll(req) 9 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/sys-manage.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '/sys/manage', 3 | title: '系统管理', 4 | icon: 'cog', 5 | children: (pre => [ 6 | { path: `${pre}user-info`, title: '个人中心', icon: 'user-circle-o' }, 7 | { path: `${pre}user-manage`, title: '用户管理', icon: 'male' } 8 | ])('/sys/manage/') 9 | } 10 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/utils/temp_code.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | from atp.api.mysql_manager import ApiTestcaseReuseRecordManager 5 | 6 | 7 | def test_insert(): 8 | ApiTestcaseReuseRecordManager.insert_record(api_testcase_id=1, total_times=10) 9 | 10 | 11 | if __name__ == '__main__': 12 | 13 | pass 14 | 15 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/guide.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw* 23 | *.zip 24 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/fixed/base.scss: -------------------------------------------------------------------------------- 1 | // 优化显示 2 | 3 | html, body { 4 | margin: 0px; 5 | height: 100%; 6 | font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; 7 | #app { 8 | @extend %full; 9 | a { 10 | text-decoration: none; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/component.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/sys/http/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | export function httpGet(url, params = {}) { 4 | return request({ 5 | url, 6 | method: 'get', 7 | params 8 | }) 9 | } 10 | 11 | export function httpPost(url, data = {}) { 12 | return request({ 13 | url, 14 | method: 'post', 15 | data 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/drag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/email.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/libs/db.js: -------------------------------------------------------------------------------- 1 | import low from 'lowdb' 2 | import LocalStorage from 'lowdb/adapters/LocalStorage' 3 | import setting from '@/setting.js' 4 | 5 | const adapter = new LocalStorage(`d2admin-${setting.releases.version}`) 6 | const db = low(adapter) 7 | 8 | db 9 | .defaults({ 10 | sys: {}, 11 | database: {} 12 | }) 13 | .write() 14 | 15 | export default db 16 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/httprunner/__about__.py: -------------------------------------------------------------------------------- 1 | __title__ = 'HttpRunner' 2 | __description__ = 'One-stop solution for HTTP(S) testing.' 3 | __url__ = 'https://github.com/HttpRunner/HttpRunner' 4 | __version__ = '1.5.11' 5 | __author__ = 'debugtalk' 6 | __author_email__ = 'mail@debugtalk.com' 7 | __license__ = 'MIT' 8 | __copyright__ = 'Copyright 2017 debugtalk' 9 | __cake__ = u'\u2728 \U0001f370 \u2728' -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/guide 2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/plugin/error/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | install(Vue, options) { 3 | Vue.config.errorHandler = function (err, vm, info) { 4 | Vue.nextTick(() => { 5 | // 只在开发模式下打印 log 6 | if (process.env.NODE_ENV === 'development') { 7 | console.log(info) 8 | console.log(vm) 9 | console.log(err) 10 | } 11 | }) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-icon/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 18 | -------------------------------------------------------------------------------- /atp-auto-core-open/flower_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | from atp.env import RUNNING_ENV 5 | 6 | broker_api_map = { 7 | 'DEV': 'http://a***:ad****@XX.XX.XX.XX:XXXX/atp_dev', 8 | 'ALIUAT': 'http://a***n:1***@WSX@XX.XX.XX.XX:XXXX/atp_uat' 9 | } 10 | 11 | # RabbitMQ management api 12 | broker_api = broker_api_map[RUNNING_ENV] 13 | 14 | # Enable debug logging 15 | logging = 'DEBUG' 16 | 17 | # 端口号 18 | port = 5555 19 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/documentation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/sys/login/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 登录接口 4 | */ 5 | export function AccountLogin(data) { 6 | return request({ 7 | url: '/atp/auto/user/login', 8 | method: 'post', 9 | data 10 | }) 11 | } 12 | 13 | /** 14 | * 登出接口 15 | */ 16 | export function AccountLogout(data) { 17 | return request({ 18 | url: '/atp/auto/user/logout', 19 | method: 'post', 20 | data 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/md5.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import hashlib 4 | 5 | salt = b'ceb20772e0c9d240c75eb26b0e37abee' 6 | 7 | 8 | def md5(*args): 9 | """ 10 | MD5加密,固定salt 11 | :param args: 12 | :return: 13 | """ 14 | m = hashlib.md5() 15 | m.update(salt) 16 | for arg in args: 17 | m.update(arg.encode(encoding='UTF-8')) 18 | 19 | return m.hexdigest() 20 | 21 | 22 | if __name__ == '__main__': 23 | pass 24 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/tools-df.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '/tools', 3 | title: '工具管理', 4 | icon: 'wrench', 5 | children: (pre => [ 6 | { 7 | path: `${pre}tool`, 8 | title: '工具集', 9 | icon: 'key', 10 | children: [ 11 | { path: `${pre}tool-loanDateToOverDueForDongFang`, title: '构造东方逾期数据' }, 12 | { path: `${pre}tool-loanTransferForDongFang`, title: '一键放款' } 13 | ] 14 | } 15 | ])('/tools/') 16 | } 17 | -------------------------------------------------------------------------------- /atp-auto-core-open/run_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | # from atp import app 4 | # from atp import socketio 5 | from atp.app import create_app 6 | app = create_app() 7 | 8 | if __name__ == '__main__': 9 | # app.run(host='0.0.0.0', port=7000, debug=True) 10 | # socketio.run(app, host='0.0.0.0', port=7000, debug=True) 11 | app.run(host='0.0.0.0', port=7000, debug=True) 12 | 13 | 14 | """ 15 | 16 | # 启动Flask服务命令 17 | python3 run_server.py 18 | 19 | """ 20 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/report-testReport/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取report 4 | */ 5 | 6 | export function queryReport(data) { 7 | return request({ 8 | url: '/atp/auto/apiReport/pagingQueryReportList', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | export function deletereport(data) { 15 | return request({ 16 | url: '/atp/auto/apiReport/delete', 17 | method: 'post', 18 | data 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/excel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-creditWhiteList/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 配置白名单接口 5 | */ 6 | 7 | export function configCredit(data) { 8 | return request({ 9 | url: '/atp/qa/configCredit', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 查询白名单接口 17 | */ 18 | 19 | export function queryCredit(data) { 20 | return request({ 21 | url: '/atp/qa/queryCredit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp_auto_init_data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO `atp_auto`.`user` (`id`, `create_time`, `update_time`, `username`, `password`, `nickname`, `level`, `user_status`) VALUES ('1', '2018-10-17 11:19:08', NULL, 'admin', '5dad3b6b71bf0584f11758423c61b51f', 'Superman', '0', '0'); 2 | INSERT INTO `atp_auto`.`user` (`id`, `create_time`, `update_time`, `username`, `password`, `nickname`, `level`, `user_status`) VALUES ('2', '2018-10-17 11:19:08', NULL, 'guest', 'ffc4aefc5b7bd14716e24134f3cf4fd1', '游客', '99', '1'); 3 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-container/components/d2-container-ghost.vue: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-loanTransfer/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询待放款订单接口 4 | */ 5 | 6 | export function queryRecentOrders(data) { 7 | return request({ 8 | url: '/atp/qa/queryRecentOrders', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 一键放款接口 16 | */ 17 | 18 | export function loanTransferSucc(data) { 19 | return request({ 20 | url: '/atp/qa/loanTransferSucc', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/real-time-log/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取运行日志 4 | */ 5 | 6 | export function getRunLog(data) { 7 | return request({ 8 | url: '/atp/auto/apiPushLog/push', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 测试报告中获取运行日志 16 | */ 17 | 18 | export function getTestReportRunLog(data) { 19 | return request({ 20 | url: '/atp/auto/apiPushLog/pushTaskLog', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testcase-apiManage/run/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 执行api测试用例 5 | */ 6 | 7 | export function run(data) { 8 | return request({ 9 | url: '/atp/auto/apiRun', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 查询api测试报告 17 | */ 18 | 19 | export function queryReportById(data) { 20 | return request({ 21 | url: '/atp/auto/apiReport/queryReportById', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-updateLogisticsInfo/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询待发货订单接口 4 | */ 5 | 6 | export function queryCollBackOrders(data) { 7 | return request({ 8 | url: '/atp/qa/queryCollBackOrders', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 发货接口 16 | */ 17 | 18 | export function collOrdersDeliver(data) { 19 | return request({ 20 | url: '/atp/qa/collOrdersDeliver', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/example.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/components/mixin/menu.js: -------------------------------------------------------------------------------- 1 | import util from '@/libs/util.js' 2 | 3 | export default { 4 | methods: { 5 | handleMenuSelect(index, indexPath) { 6 | if (/^d2-menu-empty-\d+$/.test(index) || index === undefined) { 7 | this.$message.warning('临时菜单') 8 | } else if (/^https:\/\/|http:\/\//.test(index)) { 9 | util.open(index) 10 | } else { 11 | this.$router.push({ 12 | path: index 13 | }) 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /atp-auto-core-open/supervisor/flask_atp_socket.conf.not_use: -------------------------------------------------------------------------------- 1 | [program:flask_atp_socket] 2 | command=/usr/local/miniconda3/bin/gunicorn --chdir /usr/local/src/atp/atp-auto-core/atp_socket socket_app:app -c /usr/local/src/atp/atp-auto-core/gunicorn/gunicorn_config_for_socket.py 3 | directory=/usr/local/src/atp/atp-auto-core/atp_socket/ 4 | autostart=true 5 | autorestart=true 6 | user=root 7 | environment=MOCK_SERVICE_MODE="SIT" 8 | redirect_stderr=true 9 | stdout_logfile=/usr/local/src/logs/atp-auto-core/supervisor_socket.log 10 | -------------------------------------------------------------------------------- /atp-web-open/src/api/qadata/form-batchRunData/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询所有跑批自动化项目接口 4 | */ 5 | 6 | export function queryBatchRunProject(data) { 7 | return request({ 8 | url: '/atp/qa/queryBatchRunProject', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 获取自动化定时跑批数据 16 | */ 17 | 18 | export function queryBatchRunData(data) { 19 | return request({ 20 | url: '/atp/qa/queryBatchRunData', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/integration-failReasonSet/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询需要记录失败原因的项目及构建号接口 4 | */ 5 | 6 | export function queryRecentFailPush(data) { 7 | return request({ 8 | url: '/atp/qa/queryRecentFailPush', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 登记冒烟测试失败原因 16 | */ 17 | 18 | export function recordFailure(data) { 19 | return request({ 20 | url: '/atp/qa/recordFailure', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/dataAnalysis-reuseRate/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询用例复用记录汇总 4 | */ 5 | 6 | export function getReuseSummary(data) { 7 | return request({ 8 | url: '/atp/auto/stat/getReuseSummary', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 查询用例复用记录变化趋势 16 | */ 17 | 18 | export function getReuseTrend(data) { 19 | return request({ 20 | url: '/atp/auto/stat/getReuseTrend', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-loanDataCalculate/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 贷后常用计算公式-生成还款计划:等额本息按日计息 4 | */ 5 | 6 | export function generalRepayPlanBS(data) { 7 | return request({ 8 | url: '/atp/qa/generalRepayPlanBS', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 贷后常用计算公式-全额回购 16 | */ 17 | 18 | export function calcBuybackAll(data) { 19 | return request({ 20 | url: '/atp/qa/calcBuybackAll', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/engine/exceptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import json 4 | 5 | try: 6 | JSONDecodeError = json.decoder.JSONDecodeError 7 | except AttributeError: 8 | JSONDecodeError = ValueError 9 | 10 | 11 | class LoadCaseError(BaseException): 12 | """ 13 | 组装用例时发生错误 14 | """ 15 | pass 16 | 17 | 18 | class RunCaseError(BaseException): 19 | """ 20 | 执行用例时发生错误 21 | """ 22 | pass 23 | 24 | class NoSuchElementError(BaseException): 25 | """ 26 | 元素路径错误: 27 | """ 28 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/case-report/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取任务运行summary数据 4 | */ 5 | 6 | export function getSummary(data) { 7 | return request({ 8 | url: '/atp/auto/apiTask/getSummary', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 查询用例执行具体数据 16 | */ 17 | 18 | export function getRunDataByTestcase(data) { 19 | return request({ 20 | url: '/atp/auto/apiTask/getRunDataByTestcase', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/unit/color.scss: -------------------------------------------------------------------------------- 1 | // 主色 2 | $color-primary: #409EFF; 3 | 4 | // 辅助色 5 | $color-info: #909399; 6 | $color-success: #67C23A; 7 | $color-warning: #E6A23C; 8 | $color-danger: #F56C6C; 9 | 10 | // 文字 11 | $color-text-main: #303133; 12 | $color-text-normal: #606266; 13 | $color-text-sub: #909399; 14 | $color-text-placehoder: #C0C4CC; 15 | 16 | // 边框 17 | $color-border-1: #DCDFE6; 18 | $color-border-2: #E4E7ED; 19 | $color-border-3: #EBEEF5; 20 | $color-border-4: #F2F6FC; 21 | 22 | // 背景 23 | $color-bg: #f8f8f9; -------------------------------------------------------------------------------- /atp-auto-core-open/supervisor/flask_atp_auto.conf: -------------------------------------------------------------------------------- 1 | [program:flask_atp_auto] 2 | command=/usr/local/miniconda3/bin/gunicorn run_server:app -c /usr/local/src/atp/atp-auto-core/gunicorn/gunicorn_config.py 3 | directory=/usr/local/src/atp/atp-auto-core/ 4 | autostart=false 5 | autorestart=true 6 | user=root 7 | environment=ATP_AUTO_ENV="ALIUAT" 8 | redirect_stderr=true 9 | stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB 10 | stdout_logfile_backups = 10 ; stdout 日志文件备份数 11 | stdout_logfile=/usr/local/src/logs/atp-auto-core/supervisor_auto.log 12 | -------------------------------------------------------------------------------- /atp-web-open/src/api/qadata/chart-successRateCount/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询所有自动化项目接口 4 | */ 5 | 6 | export function queryAutotestProject(data) { 7 | return request({ 8 | url: '/atp/qa/queryAutotestProject', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 按月查询自动化用例执行结果接口 16 | */ 17 | 18 | export function queryAutotestResultByMonth(data) { 19 | return request({ 20 | url: '/atp/qa/queryAutotestResultByMonth', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /atp-auto-core-open/supervisor/flask_atp_celery_monitor.conf: -------------------------------------------------------------------------------- 1 | [program:flask_atp_celery_monitor] 2 | command=/usr/local/miniconda3/bin/celery -A run_celery:celery flower --conf=flower_config.py 3 | directory=/usr/local/src/atp/atp-auto-core/ 4 | autostart=false 5 | autorestart=true 6 | user=root 7 | environment=ATP_AUTO_ENV="ALIUAT" 8 | redirect_stderr=true 9 | stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB 10 | stdout_logfile_backups = 10 ; stdout 日志文件备份数 11 | stdout_logfile=/usr/local/src/logs/atp-auto-core/supervisor_celery_monitor.log 12 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/config/load_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | def load_config(mode): 5 | try: 6 | if mode == "DEV": 7 | from atp.config.dev import DevConfig 8 | return DevConfig 9 | elif mode == "ALIUAT": 10 | from atp.config.aliuat import AliuatConfig 11 | return AliuatConfig 12 | else: 13 | raise ValueError("ENV MODE selection out of range") 14 | except ValueError as e: 15 | from atp.config.dev import DevConfig 16 | return DevConfig 17 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/gray.js: -------------------------------------------------------------------------------- 1 | export default { 2 | namespaced: true, 3 | state: { 4 | // 灰度 5 | active: false 6 | }, 7 | mutations: { 8 | /** 9 | * @description 切换灰度状态 10 | * @param {Object} state vuex state 11 | */ 12 | toggle(state) { 13 | state.active = !state.active 14 | }, 15 | /** 16 | * @description 设置灰度模式 17 | * @param {Object} state vuex state 18 | * @param {Boolean} active active 19 | */ 20 | set(state, active) { 21 | state.active = active 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/star.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-container/components/d2-container-full.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /atp-auto-core-open/supervisor/flask_atp_celery_task.conf: -------------------------------------------------------------------------------- 1 | [program:flask_atp_celery_task] 2 | command=/usr/local/miniconda3/bin/celery worker -A run_celery:celery -c 10 -Q for_task -n for_task.%%h -l info -f /usr/local/src/logs/atp-auto-core/celery_task.log 3 | directory=/usr/local/src/atp/atp-auto-core/ 4 | autostart=false 5 | autorestart=true 6 | user=root 7 | environment=ATP_AUTO_ENV="ALIUAT" 8 | redirect_stderr=true 9 | stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB 10 | stdout_logfile_backups = 10 ; stdout 日志文件备份数 11 | stdout_logfile=/usr/local/src/logs/atp-auto-core/supervisor_celery_task.log 12 | -------------------------------------------------------------------------------- /atp-auto-core-open/supervisor/flask_atp_celery_task_sit.conf: -------------------------------------------------------------------------------- 1 | [program:flask_atp_celery_task_sit] 2 | command=/usr/local/miniconda3/bin/celery worker -A run_celery:celery -c 1 -Q for_task -n for_task.%%h -l info -f /usr/local/src/logs/atp-auto-core/celery_task.log 3 | directory=/usr/local/src/atp/atp-auto-core/ 4 | autostart=false 5 | autorestart=true 6 | user=root 7 | environment=ATP_AUTO_ENV="ALIUAT" 8 | redirect_stderr=true 9 | stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB 10 | stdout_logfile_backups = 10 ; stdout 日志文件备份数 11 | stdout_logfile=/usr/local/src/logs/atp-auto-core/supervisor_celery_task.log 12 | -------------------------------------------------------------------------------- /atp-auto-core-open/supervisor/flask_atp_celery_default.conf: -------------------------------------------------------------------------------- 1 | [program:flask_atp_celery_default] 2 | command=/usr/local/miniconda3/bin/celery worker -A run_celery:celery -c 5 -Q default -n default.%%h -l info -f /usr/local/src/logs/atp-auto-core/celery_default.log 3 | directory=/usr/local/src/atp/atp-auto-core/ 4 | autostart=false 5 | autorestart=true 6 | user=root 7 | environment=ATP_AUTO_ENV="ALIUAT" 8 | redirect_stderr=true 9 | stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB 10 | stdout_logfile_backups = 10 ; stdout 日志文件备份数 11 | stdout_logfile=/usr/local/src/logs/atp-auto-core/supervisor_celery_default.log 12 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/ua.js: -------------------------------------------------------------------------------- 1 | import UaParser from 'ua-parser-js' 2 | // import {getIPs} from '@/libs/common' 3 | 4 | export default { 5 | namespaced: true, 6 | state: { 7 | // 用户 UA 8 | data: {}, 9 | ip: '0.0.0.0' 10 | }, 11 | getters: { 12 | ip: state => state.ip 13 | }, 14 | mutations: { 15 | /** 16 | * @description 记录 UA 17 | * @param {Object} state vuex state 18 | */ 19 | get(state) { 20 | state.data = new UaParser().getResult() 21 | /* getIPs(function(ip){ 22 | state.ip = ip 23 | })*/ 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /atp-auto-core-open/supervisor/flask_atp_celery_default_sit.conf: -------------------------------------------------------------------------------- 1 | [program:flask_atp_celery_default_sit] 2 | command=/usr/local/miniconda3/bin/celery worker -A run_celery:celery -c 1 -Q default -n default.%%h -l info -f /usr/local/src/logs/atp-auto-core/celery_default.log 3 | directory=/usr/local/src/atp/atp-auto-core/ 4 | autostart=false 5 | autorestart=true 6 | user=root 7 | environment=ATP_AUTO_ENV="ALIUAT" 8 | redirect_stderr=true 9 | stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB 10 | stdout_logfile_backups = 10 ; stdout 日志文件备份数 11 | stdout_logfile=/usr/local/src/logs/atp-auto-core/supervisor_celery_default.log 12 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/animate/vue-transition.scss: -------------------------------------------------------------------------------- 1 | // 过渡动画 横向渐变 2 | .fade-transverse-leave-active, 3 | .fade-transverse-enter-active { 4 | transition: all .5s; 5 | } 6 | .fade-transverse-enter { 7 | opacity: 0; 8 | transform: translateX(-30px); 9 | } 10 | .fade-transverse-leave-to { 11 | opacity: 0; 12 | transform: translateX(30px); 13 | } 14 | 15 | // 过渡动画 缩放渐变 16 | .fade-scale-leave-active, 17 | .fade-scale-enter-active { 18 | transition: all .5s; 19 | } 20 | .fade-scale-enter { 21 | opacity: 0; 22 | transform: scale(1.2); 23 | } 24 | .fade-scale-leave-to { 25 | opacity: 0; 26 | transform: scale(0.8); 27 | } -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/fixed/element.scss: -------------------------------------------------------------------------------- 1 | // element 样式补丁 2 | 3 | .el-card { 4 | &.is-always-shadow { 5 | box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5); 6 | } 7 | &.is-hover-shadow { 8 | &:hover { 9 | box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5); 10 | } 11 | } 12 | } 13 | 14 | .el-menu--horizontal { 15 | border-bottom: none !important; 16 | } 17 | 18 | .el-tabs__item:focus.is-active.is-focus:not(:active) { 19 | box-shadow: none !important; 20 | } 21 | 22 | /*.el-table .el-table__header th { 23 | color: black; 24 | background: rgb(238, 241, 246); 25 | }*/ 26 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-container/components/d2-container-card.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/folder_open_directory_category_browse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Svg Vector Icons : http://www.sfont.cn 6 | 7 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/httprunner/templates/locustfile_template: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | import zmq 3 | from locust import HttpLocust, TaskSet, task 4 | from httprunner import LocustRunner 5 | 6 | 7 | class WebPageTasks(TaskSet): 8 | def on_start(self): 9 | self.test_runner = LocustRunner(self.client) 10 | self.file_path = self.locust.file_path 11 | 12 | @task 13 | def test_specified_scenario(self): 14 | self.test_runner.run(self.file_path) 15 | 16 | 17 | class WebPageUser(HttpLocust): 18 | host = "$HOST" 19 | task_set = WebPageTasks 20 | min_wait = 1000 21 | max_wait = 5000 22 | 23 | file_path = "$TESTCASE_FILE" 24 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-container/components/d2-container-ghost-bs.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 22 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testcase-run/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 执行api测试用例 5 | */ 6 | 7 | export function run(data) { 8 | return request({ 9 | url: '/atp/auto/run', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 执行UI自动化 17 | */ 18 | 19 | export function runUiCase(data) { 20 | return request({ 21 | url: '/atp/auto/run_ui', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 查询api测试报告 29 | */ 30 | 31 | export function queryReportById(data) { 32 | return request({ 33 | url: '/atp/auto/apiReport/queryReportById', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/theme.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-setMatchFund/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 设置资方匹配规则 4 | */ 5 | 6 | export function setFundMatch(data) { 7 | return request({ 8 | url: '/atp/qa/setFundMatch', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 查询已配置的资方匹配规则 16 | */ 17 | 18 | export function queryFundMatchSettings(data) { 19 | return request({ 20 | url: '/atp/qa/queryFundMatchSettings', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 删除资方匹配规则 28 | */ 29 | 30 | export function deleteFundMatch(data) { 31 | return request({ 32 | url: '/atp/qa/deleteFundMatch', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-loanDateToOverDue/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 指定放款时间重新生成还款计划+逾期跑批 4 | */ 5 | 6 | export function createAccountingOverdue(data) { 7 | return request({ 8 | url: '/atp/qa/createAccountingOverdue', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 指定放款时间只生成还款计划 16 | */ 17 | 18 | export function updateLoanPlan(data) { 19 | return request({ 20 | url: '/atp/qa/updateLoanPlan', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 逾期跑批 28 | */ 29 | 30 | export function executeOverdue(data) { 31 | return request({ 32 | url: '/atp/qa/executeOverdue', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/qadata.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '/qadata', 3 | title: '质量管理', 4 | icon: 'pie-chart', 5 | children: (pre => [ 6 | { 7 | path: `${pre}form`, 8 | title: '表格', 9 | icon: 'bar-chart', 10 | children: [ 11 | { path: `${pre}form-autoTestData`, title: '自动化运行汇总数据' }, 12 | { path: `${pre}form-batchRunData`, title: '自动化定时跑批数据' }, 13 | { path: `${pre}form-bugDataStatistics`, title: '缺陷统计数据' } 14 | ] 15 | }, 16 | { 17 | path: `${pre}chart`, 18 | title: '图表', 19 | icon: 'area-chart', 20 | children: [ 21 | { path: `${pre}chart-successRateCount`, title: '按执行成功率统计' } 22 | ] 23 | } 24 | ])('/qadata/') 25 | } 26 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/interfaces.js: -------------------------------------------------------------------------------- 1 | export default { 2 | namespaced: true, 3 | state: { 4 | 5 | // 业务用例列表数据 6 | interfaceTable: { 7 | interfaceId: '', 8 | id: 0 9 | }, 10 | // 是否点击添加测试用例菜单 11 | addCaseVisible: false 12 | }, 13 | 14 | // getters: { 15 | // // PublicVariabletableData: state => state.PublicVariabletableData 16 | // }, 17 | // 用例树上切换不同节点,展示相应的用例数据 18 | mutations: { 19 | changeInterfaceTableStatus(state, interfaceIdTable) { 20 | state.interfaceTable = { 21 | interfaceId: interfaceIdTable.interfaceId 22 | } 23 | }, 24 | addCase(state, addCaseVisible) { 25 | state.addCaseVisible = addCaseVisible 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/peoples.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-container/components/d2-container-full-bs.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /atp-auto-core-open/README.md: -------------------------------------------------------------------------------- 1 | # atp-auto-core 2 | 基于flask、sqlalchemy、httprunner、celery等构建的自动化后台。 3 | 4 | ## 环境要求 5 | ``` 6 | python3.6 7 | 其他依赖包见requirement.txt 8 | ``` 9 | 10 | ### 发布 11 | ``` 12 | 部署目录 : /usr/local/src/atp/atp-auto-core 13 | 启动方式 : 通过supervisor启动flask_atp_auto、flask_atp_celery_default、flask_atp_celery_task服务,在supervisor配置文件中include项目目录下supervisor下所有配置文件 14 | ``` 15 | 16 | ### 目录说明 17 | ``` 18 | atp : 代码目录 19 | 1、api : 公共处理函数 20 | 2、config : 不同环境配置文件 21 | 3、engine : 核心方法,如加载用例、celery任务等 22 | 4、httprunner : 第三方测试框架 23 | 5、jobs : celery定时任务 24 | 6、models : 模型文件 25 | 7、utils : 工具类,一些通用方法 26 | 8、views : 视图文件 27 | gunicon : gunicon配置文件 28 | supervisor : supervisor配置文件 29 | flower_config.py celery控制台 30 | run_celery.py celery任务启动脚本 31 | run_server.py flask工程启动脚本 32 | ``` 33 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/engine/code_to_desc.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | def get_desc_by_case_type(case_type): 5 | if case_type == 1: 6 | return "接口用例" 7 | elif case_type == 2: 8 | return "全链路用例" 9 | 10 | 11 | def get_case_type_by_desc(desc): 12 | if desc == "接口用例": 13 | return 1 14 | elif desc == "全链路用例": 15 | return 2 16 | 17 | 18 | def get_desc_by_case_status(case_status): 19 | if case_status == 0: 20 | return "启用中" 21 | elif case_status == 1: 22 | return "已停用" 23 | else: 24 | return "已停用" 25 | 26 | 27 | def get_desc_by_last_run(last_run): 28 | if last_run == 0: 29 | return "成功" 30 | elif last_run == 1: 31 | return "失败" 32 | else: 33 | return "未运行" 34 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/dataAnalysis-regressionResult/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询测试任务运行结果 4 | */ 5 | 6 | export function getRunResults(data) { 7 | return request({ 8 | url: '/atp/auto/apiTask/getRunResults', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 查询某一天的测试任务运行结果 16 | */ 17 | 18 | export function getRunResultBySingleDay(data) { 19 | return request({ 20 | url: '/atp/auto/apiTask/getRunResultBySingleDay', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 下载测试任务运行结果 28 | */ 29 | 30 | export function exportSummaryToExcel(data) { 31 | return request({ 32 | url: '/atp/auto/apiTask/exportSummaryToExcel', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/resource-apiManage/project/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 根据公司id查询 公司下所有的项目 5 | */ 6 | 7 | export function queryProjectByCompanyId(data) { 8 | return request({ 9 | url: '/atp/auto/apiProject/list', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 根据项目id获取引入的接口列表 17 | */ 18 | 19 | export function getIncludeIntfList(data) { 20 | return request({ 21 | url: '/atp/auto/apiProject/getIncludeIntfList', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 根据项目id查询系统、接口、用例树 29 | */ 30 | 31 | export function getSubTreeByProjectId(data) { 32 | return request({ 33 | url: '/atp/auto/apiProject/subtree', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /atp-web-open/src/config/mqtt.js: -------------------------------------------------------------------------------- 1 | export const MQTT_SERVICE = { // mqtt服务地址 2 | 'atp_dev': 'ws://99.48.58.241:15674/ws', 3 | 'atp_uat': 'ws://192.168.10.54:15674/ws', 4 | 'atp_oq': 'ws://192.168.151.160:15674/ws', 5 | 'atp_df': 'ws://192.168.183.229:15674/ws', 6 | 'atp_bf': 'ws://192.168.199.57:15674/ws', 7 | 'atp_qj': 'ws://192.168.215.177:15674/ws' 8 | } 9 | export const MQTT_USERNAME = { // mqtt连接用户名 10 | 'atp_dev': 'admin', 11 | 'atp_uat': 'admin', 12 | 'atp_oq': 'admin', 13 | 'atp_df': 'admin', 14 | 'atp_bf': 'admin', 15 | 'atp_qj': 'admin' 16 | } 17 | export const MQTT_PASSWORD = { // mqtt连接密码 18 | 'atp_dev': 'admin', 19 | 'atp_uat': '1qaz@WSX', 20 | 'atp_oq': '1qaz@WSX', 21 | 'atp_df': '1qaz@WSX', 22 | 'atp_bf': '1qaz@WSX', 23 | 'atp_qj': '1qaz@WSX' 24 | } 25 | 26 | -------------------------------------------------------------------------------- /atp-web-open/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= VUE_APP_TITLE %> 9 | 16 | 17 | 18 | 21 |
22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/nested.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-container/components/d2-container-card-bs.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 26 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/libs/util.js: -------------------------------------------------------------------------------- 1 | import cookies from './util.cookies.js' 2 | 3 | let util = { 4 | cookies 5 | } 6 | 7 | /** 8 | * @description 更新标题 9 | * @param {String} title 标题 10 | */ 11 | util.title = function (titleText) { 12 | const processTitle = process.env.VUE_APP_TITLE || 'D2Admin' 13 | window.document.title = `${processTitle}${titleText ? ` | ${titleText}` : ''}` 14 | } 15 | 16 | /** 17 | * @description 打开新页面 18 | * @param {String} url 地址 19 | */ 20 | util.open = function (url) { 21 | var a = document.createElement('a') 22 | a.setAttribute('href', url) 23 | a.setAttribute('target', '_blank') 24 | a.setAttribute('id', 'd2admin-menu-link') 25 | document.body.appendChild(a) 26 | a.click() 27 | document.body.removeChild(document.getElementById('d2admin-menu-link')) 28 | } 29 | 30 | export default util 31 | -------------------------------------------------------------------------------- /atp-web-open/src/plugin/d2admin/index.js: -------------------------------------------------------------------------------- 1 | // Element 2 | import ElementUI from 'element-ui' 3 | import 'element-ui/lib/theme-chalk/index.css' 4 | // flex 布局库 5 | import 'flex.css' 6 | // 组件 7 | import '@/components' 8 | // 功能插件 9 | import pluginError from '@/plugin/error' 10 | import pluginOpen from '@/plugin/open' 11 | 12 | export default { 13 | install(Vue, options) { 14 | // Element 15 | Vue.use(ElementUI, { size: 'small' }) 16 | // 插件 17 | Vue.use(pluginError) 18 | Vue.use(pluginOpen) 19 | // 设置为 false 以阻止 vue 在启动时生成生产提示。 20 | // https://cn.vuejs.org/v2/api/#productionTip 21 | Vue.config.productionTip = false 22 | // 当前环境 23 | Vue.prototype.$env = process.env.NODE_ENV 24 | // 当前的 baseUrl 25 | // 简化代码中 process.env.BASE_URL 取值 26 | Vue.prototype.$baseUrl = process.env.BASE_URL 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/components/header-user/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 32 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/testreport.js: -------------------------------------------------------------------------------- 1 | export default { 2 | namespaced: true, 3 | state: { 4 | // 测试报告信息 5 | info: {} 6 | }, 7 | actions: { 8 | setReportId({ commit }) { 9 | commit('load') 10 | } 11 | }, 12 | mutations: { 13 | // 存储测试报告信息 14 | set(state, info) { 15 | // store 赋值 16 | state.info = info 17 | // 持久化 18 | this.dispatch('d2admin/db/set', { 19 | dbName: 'sys', 20 | path: 'report.info', 21 | value: state.info, 22 | user: true 23 | }) 24 | }, 25 | // 读取测试报告信息 26 | async load(state) { 27 | // store 赋值 28 | state.info = await this.dispatch('d2admin/db/get', { 29 | dbName: 'sys', 30 | path: 'report.info', 31 | defaultValue: {}, 32 | user: true 33 | }) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/resource-envManage/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 添加环境 5 | */ 6 | 7 | export function addEnv(data) { 8 | return request({ 9 | url: '/atp/auto/env/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 修改环境 17 | */ 18 | 19 | export function editEnv(data) { 20 | return request({ 21 | url: '/atp/auto/env/edit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 删除环境 29 | */ 30 | 31 | export function deleteEnv(data) { 32 | return request({ 33 | url: '/atp/auto/env/delete', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 获取环境列表 41 | */ 42 | 43 | export function fetchEnvList(data) { 44 | return request({ 45 | url: '/atp/auto/env/list', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /atp-web-open/src/setting.js: -------------------------------------------------------------------------------- 1 | import { version } from '../package' 2 | 3 | const setting = { 4 | // 侧边栏默认折叠状态 5 | menu: { 6 | asideCollapse: false 7 | }, 8 | // 在读取持久化数据失败时默认页面 9 | page: { 10 | opened: [ 11 | { 12 | name: 'index', 13 | meta: { 14 | title: '首页', 15 | requiresAuth: false 16 | } 17 | } 18 | ] 19 | }, 20 | // 版本 21 | releases: { 22 | version: version 23 | }, 24 | // 注册的主题 25 | theme: { 26 | list: [ 27 | { 28 | title: 'atp', 29 | name: 'atp', 30 | preview: 'image/theme/atp/preview@2x.png' 31 | } 32 | ] 33 | }, 34 | // 是否默认开启页面切换动画 35 | transition: { 36 | active: true 37 | }, 38 | // 在读取持久化数据失败时默认用户信息 39 | user: { 40 | info: { 41 | name: 'Ghost' 42 | } 43 | } 44 | } 45 | 46 | export default setting 47 | -------------------------------------------------------------------------------- /atp-web-open/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 33 | 34 | 43 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/index.js: -------------------------------------------------------------------------------- 1 | import db from './modules/db' 2 | import user from './modules/user' 3 | import menu from './modules/menu' 4 | import theme from './modules/theme' 5 | import account from './modules/account' 6 | import ua from './modules/ua' 7 | import gray from './modules/gray' 8 | import page from './modules/page' 9 | import transition from './modules/transition' 10 | import casetable from './modules/casetable' 11 | import testreport from './modules/testreport' 12 | import interfaces from './modules/interfaces' 13 | import fulllinecase from './modules/fulllinecase' 14 | export default { 15 | namespaced: true, 16 | modules: { 17 | db, 18 | user, 19 | menu, 20 | theme, 21 | account, 22 | ua, 23 | gray, 24 | page, 25 | transition, 26 | casetable, 27 | interfaces, 28 | testreport, 29 | fulllinecase 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/components/components/menu-item/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/public.scss: -------------------------------------------------------------------------------- 1 | @import '~@/assets/style/unit/color.scss'; 2 | 3 | // 工具类名统一前缀 4 | $prefix: d2; 5 | 6 | // 禁止用户选中 鼠标变为手形 7 | %unable-select { 8 | user-select: none; 9 | cursor: pointer; 10 | } 11 | 12 | // 填满父元素 13 | // 组要父元素 position: relative | absolute; 14 | %full { 15 | position: absolute; 16 | top: 0px; 17 | right: 0px; 18 | bottom: 0px; 19 | left: 0px; 20 | } 21 | 22 | // flex 垂直水平居中 23 | %flex-center-row { 24 | display: flex; 25 | justify-content: center; 26 | align-items: center; 27 | flex-direction: row; 28 | } 29 | %flex-center-col { 30 | display: flex; 31 | justify-content: center; 32 | align-items: center; 33 | flex-direction: column; 34 | } 35 | 36 | // 将元素模拟成卡片外观 37 | %card { 38 | border: 1px solid #dddee1; 39 | border-color: #e9eaec; 40 | background: #fff; 41 | border-radius: 4px; 42 | font-size: 14px; 43 | position: relative; 44 | } -------------------------------------------------------------------------------- /atp-web-open/README.md: -------------------------------------------------------------------------------- 1 | # atp-platform-web 2 | 基于vue2.0, d2admin, element-ui 定制开发。 3 | 4 | ## 项目安装 5 | ``` 6 | npm install 7 | ``` 8 | 9 | ### 启动本地调试 10 | ``` 11 | npm run serve 12 | ``` 13 | 14 | ### 打包生产环境 15 | ``` 16 | npm run master 17 | ``` 18 | 19 | ### 目录说明 20 | ``` 21 | public : 资源路径,存放一些图标、图片 22 | src : 代码目录 23 | 1、api : 定义后台接口 24 | 2、assets : css样式(属于d2admin框架内容) 25 | 3、components : 自定义组件(属于d2admin框架内容) 26 | 4、config : mq配置文件,区分不同环境 27 | 5、icons : icons图标资源 28 | 6、layout : 整体布局(属于d2admin框架内容) 29 | 7、libs : 定义公共方法 30 | 8、menu : 配置菜单 31 | 9、pages : 定义具体页面 32 | 10、plugin : 通用插件,如axios请求拦截器等(属于d2admin框架内容) 33 | 11、router : 路由配置 34 | .env.xxx 不同环境配置文件 35 | package.json 打包命令及依赖包 36 | vue.config.js webpack配置,如代理服务器devServer配置 37 | ``` 38 | 39 | 40 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/get_log_content.py: -------------------------------------------------------------------------------- 1 | 2 | class GetLogContent(object): 3 | """ 4 | 获取服务器日志文件内容 5 | """ 6 | def __init__(self, logs, start_with, end_with): 7 | self.logs = logs 8 | self.start_with = start_with 9 | self.end_with = end_with 10 | 11 | def get_log_content(self): 12 | """ 13 | 解析日志内容,根据起始标签,找到符合要求的内容列表,然后根据搜索关键字找到符合条件的内容 14 | :return: 15 | """ 16 | if self.start_with and self.end_with: 17 | filtered_logs = self.logs.split(self.start_with)[1].split(self.end_with)[0] 18 | elif self.start_with: 19 | filtered_logs = self.logs.split(self.start_with)[1] 20 | elif self.end_with: 21 | filtered_logs = self.logs.split(self.end_with)[0] 22 | else: 23 | filtered_logs = self.logs 24 | 25 | return filtered_logs 26 | 27 | 28 | if __name__ == '__main__': 29 | pass 30 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/fullLineCase/produceLine-config/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 添加产品线 5 | */ 6 | 7 | export function addProductLine(data) { 8 | return request({ 9 | url: '/atp/auto/apiProductLine/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 删除产品线 17 | */ 18 | 19 | export function deleteProductLine(data) { 20 | return request({ 21 | url: '/atp/auto/apiProductLine/delete', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 编辑产品线 29 | */ 30 | 31 | export function editProductLine(data) { 32 | return request({ 33 | url: '/atp/auto/apiProductLine/edit', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 变更目录结构 41 | */ 42 | 43 | export function changeParent(data) { 44 | return request({ 45 | url: '/atp/auto/apiProductLine/changeParent', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | 51 | -------------------------------------------------------------------------------- /atp-web-open/src/api/mock/mock-config/interface/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 新增mock接口 5 | */ 6 | 7 | export function addMockInterface(data) { 8 | return request({ 9 | url: '/atp/mock/config/interface/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 修改mock接口 17 | */ 18 | 19 | export function editMockInterface(data) { 20 | return request({ 21 | url: '/atp/mock/config/interface/edit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 删除mock接口 29 | */ 30 | 31 | export function delMockInterface(data) { 32 | return request({ 33 | url: '/atp/mock/config/interface/delete', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 查询mock接口详情 41 | */ 42 | 43 | export function queryMockInterfaceDetail(data) { 44 | return request({ 45 | url: '/atp/mock/config/interface/detail', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /atp-web-open/src/api/monitor/businessStatus/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取系统实时状态 4 | */ 5 | 6 | export function getSystemStatus(data) { 7 | return request({ 8 | url: '/atp/monitor/businessStatus/list', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 重启故障系统 16 | */ 17 | 18 | export function rebootSystem(data) { 19 | return request({ 20 | url: '/atp/monitor/businessStatus/reboot', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 获取最近一次系统状态 28 | */ 29 | 30 | export function getLastStatus(data) { 31 | return request({ 32 | url: '/atp/monitor/businessStatus/getLastStatus', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | 38 | /** 39 | * 获取当前所有历史监控记录 40 | */ 41 | 42 | export function getCurrentDayHis(data) { 43 | return request({ 44 | url: '/atp/monitor/businessStatus/getCurrentDayHis', 45 | method: 'post', 46 | data 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /atp-web-open/src/api/mock/mock-config/project/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 新增需要配置mock数据的系统 5 | */ 6 | 7 | export function addMockProject(data) { 8 | return request({ 9 | url: '/atp/mock/config/project/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 修改需要配置mock数据的系统 17 | */ 18 | 19 | export function editMockProject(data) { 20 | return request({ 21 | url: '/atp/mock/config/project/edit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 删除需要配置mock数据的系统 29 | */ 30 | 31 | export function delMockProject(data) { 32 | return request({ 33 | url: '/atp/mock/config/project/delete', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 查询已配置的mock接口列表 41 | */ 42 | 43 | export function queryMockInterfaces(data) { 44 | return request({ 45 | url: '/atp/mock/config/project/query', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/git_api.py: -------------------------------------------------------------------------------- 1 | 2 | import gitlab 3 | 4 | from atp.config.load_config import load_config 5 | from atp.env import RUNNING_ENV 6 | 7 | _config = load_config(RUNNING_ENV) 8 | 9 | 10 | class GitlabAPI(object): 11 | def __init__(self): 12 | self.gl = gitlab.Gitlab(_config.GIT_URL, _config.GIT_PRIVATE_TOKEN) 13 | 14 | def get_all_projects(self): 15 | projects = self.gl.projects.list(all=True) 16 | result_list = [] 17 | for project in projects: 18 | result_list.append(project.ssh_url_to_repo) 19 | return result_list 20 | 21 | def get_project_branches(self, userspace_name): 22 | project = self.gl.projects.get(userspace_name) 23 | branches_name_list = [] 24 | for branch in project.branches.list(): 25 | branches_name_list.append(branch.name) 26 | return branches_name_list 27 | 28 | if __name__ == '__main__': 29 | git = GitlabAPI() 30 | print(git.get_all_projects()) 31 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-container/components/mixins/bs.js: -------------------------------------------------------------------------------- 1 | import BScroll from 'better-scroll' 2 | export default { 3 | props: { 4 | betterScrollOptions: { 5 | type: Object, 6 | required: false, 7 | default: () => ({}) 8 | } 9 | }, 10 | data() { 11 | return { 12 | BS: null 13 | } 14 | }, 15 | mounted() { 16 | this.scrollInit() 17 | }, 18 | beforeDestroy() { 19 | this.scrollDestroy() 20 | }, 21 | methods: { 22 | scrollInit() { 23 | this.BS = new BScroll(this.$refs.wrapper, Object.assign({ 24 | mouseWheel: true, 25 | scrollbar: { 26 | fade: true, 27 | interactive: false 28 | } 29 | }, this.betterScrollOptions)) 30 | }, 31 | scrollDestroy() { 32 | // https://github.com/d2-projects/d2-admin/issues/75 33 | try { 34 | this.BS.destroy() 35 | } catch (e) { 36 | delete this.BS 37 | this.BS = null 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/user.js: -------------------------------------------------------------------------------- 1 | // 设置文件 2 | import setting from '@/setting.js' 3 | 4 | export default { 5 | namespaced: true, 6 | state: { 7 | // 用户信息 8 | info: setting.user.info 9 | }, 10 | mutations: { 11 | /** 12 | * @description 设置用户数据 13 | * @param {Object} state vuex state 14 | * @param {*} info info 15 | */ 16 | set(state, info) { 17 | // store 赋值 18 | state.info = info 19 | // 持久化 20 | this.dispatch('d2admin/db/set', { 21 | dbName: 'sys', 22 | path: 'user.info', 23 | value: state.info, 24 | user: true 25 | }) 26 | }, 27 | /** 28 | * @description 从数据库取用户数据 29 | * @param {Object} state vuex state 30 | */ 31 | async load(state) { 32 | // store 赋值 33 | state.info = await this.dispatch('d2admin/db/get', { 34 | dbName: 'sys', 35 | path: 'user.info', 36 | defaultValue: setting.user.info, 37 | user: true 38 | }) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/utils/map_functions.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | def map_testcase_type_to_number(intf_type): 5 | """ 6 | 接口类型映射关系 7 | :param intf_type: 8 | :return: 9 | """ 10 | if intf_type == "HTTP": 11 | return 1 12 | elif intf_type == "DUBBO": 13 | return 2 14 | elif intf_type == "MQ": 15 | return 3 16 | 17 | 18 | def map_number_to_testcase_type(number): 19 | """ 20 | 接口类型映射关系 21 | :param number: 22 | :return: 23 | """ 24 | if number == 1: 25 | return "HTTP" 26 | elif number == 2: 27 | return "DUBBO" 28 | elif number == 3: 29 | return "MQ" 30 | 31 | 32 | def map_number_to_case_status(number): 33 | if number == 0: 34 | return "启用中" 35 | elif number == 1: 36 | return "已停用" 37 | else: 38 | return "已停用" 39 | 40 | 41 | def map_number_to_last_run(number): 42 | if number == 0: 43 | return "成功" 44 | elif number == 1: 45 | return "失败" 46 | else: 47 | return "未运行" 48 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/libs/util.cookies.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const cookies = {} 4 | 5 | /** 6 | * @description 存储 cookie 值 7 | * @param {String} name cookie name 8 | * @param {String} value cookie value 9 | * @param {Object} setting cookie setting 10 | */ 11 | cookies.set = function (name = 'default', value = '', cookieSetting = {}) { 12 | let currentCookieSetting = { 13 | expires: 1 14 | } 15 | Object.assign(currentCookieSetting, cookieSetting) 16 | Cookies.set(`${name}`, value, currentCookieSetting) 17 | } 18 | 19 | /** 20 | * @description 拿到 cookie 值 21 | * @param {String} name cookie name 22 | */ 23 | cookies.get = function (name = 'default') { 24 | return Cookies.get(`${name}`) 25 | } 26 | 27 | /** 28 | * @description 拿到 cookie 全部的值 29 | */ 30 | cookies.getAll = function () { 31 | return Cookies.get() 32 | } 33 | 34 | /** 35 | * @description 删除 cookie 36 | * @param {String} name cookie name 37 | */ 38 | cookies.remove = function (name = 'default') { 39 | return Cookies.remove(`${name}`) 40 | } 41 | 42 | export default cookies 43 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/transition.js: -------------------------------------------------------------------------------- 1 | // 设置文件 2 | import setting from '@/setting.js' 3 | 4 | export default { 5 | namespaced: true, 6 | state: { 7 | // 是否开启页面过度动画 8 | active: setting.transition.active 9 | }, 10 | mutations: { 11 | /** 12 | * @description 设置开启状态 13 | * @param {Object} state vuex state 14 | * @param {Boolean} active 新的状态 15 | */ 16 | set(state, active) { 17 | // store 赋值 18 | state.active = active 19 | // 持久化 20 | this.dispatch('d2admin/db/set', { 21 | dbName: 'sys', 22 | path: 'transition.active', 23 | value: state.active, 24 | user: true 25 | }) 26 | }, 27 | /** 28 | * 从数据库读取页面过渡动画设置 29 | * @param {Object} state vuex state 30 | */ 31 | async load(state) { 32 | // store 赋值 33 | state.active = await this.dispatch('d2admin/db/get', { 34 | dbName: 'sys', 35 | path: 'transition.active', 36 | defaultValue: setting.transition.active, 37 | user: true 38 | }) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/config/dev.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import platform 4 | 5 | from atp.config.default import Config 6 | 7 | 8 | class DevConfig(Config): 9 | # redis 10 | REDIS_HOST = '' 11 | REDIS_PORT = 6379 12 | REDIS_DB_18 = 18 13 | REDIS_PASSWORD = '' 14 | 15 | # mysql 16 | if platform.system() == 'Linux': 17 | SQLALCHEMY_DATABASE_URI = "" 18 | elif platform.system() == 'Windows': 19 | SQLALCHEMY_DATABASE_URI = "" 20 | 21 | elif platform.system() == 'Darwin': 22 | SQLALCHEMY_DATABASE_URI = "" 23 | else: 24 | SQLALCHEMY_DATABASE_URI = "" 25 | 26 | # 基线用例需要解析的文件夹命名列表 27 | BASELINE_DIR_NAME_LIST = ['A', 'B'] 28 | 29 | # gitlab相关配置 30 | GIT_URL = "http://" 31 | GIT_PRIVATE_TOKEN = "" 32 | GIT_API_VERSION = 3 33 | 34 | # celery任务相关配置 35 | BROKER_URL = 'amqp://' 36 | CELERY_RESULT_BACKEND = 'amqp://' 37 | 38 | # RabbitMQ 39 | RABBIT_HOST = '' 40 | RABBIT_USERNAME = '' # 指定远程rabbitmq的用户名 41 | RABBIT_PWD = '' # 密码 42 | RABBIT_PORT = 5672 43 | RABBIT_V_HOST = '' 44 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/international.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/config/aliuat.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import platform 4 | 5 | from atp.config.default import Config 6 | 7 | 8 | class AliuatConfig(Config): 9 | # redis 10 | REDIS_HOST = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 11 | REDIS_PORT = 232 12 | REDIS_DB_18 = 23 13 | REDIS_PASSWORD = 'XXXXXXXXXXXXXX' 14 | 15 | # mysql 16 | if platform.system() == 'Linux': 17 | SQLALCHEMY_DATABASE_URI = "" 18 | elif platform.system() == 'Windows': 19 | SQLALCHEMY_DATABASE_URI = "" 20 | elif platform.system() == 'Darwin': 21 | SQLALCHEMY_DATABASE_URI = "" 22 | else: 23 | SQLALCHEMY_DATABASE_URI = "" 24 | 25 | # 基线用例需要解析的文件夹命名列表 26 | BASELINE_DIR_NAME_LIST = ['A', 'B'] 27 | 28 | 29 | BROKER_URL = '' 30 | CELERY_RESULT_BACKEND = '' 31 | 32 | # apt-monitor 33 | ATP_MONITOR_SYSTEMS = [] 34 | ATP_MONITOR_LIST = '' 35 | ATP_MONITOR_REBOOT = '' 36 | 37 | # RabbitMQ 38 | RABBIT_HOST = 'XX.XX.XX.XX' 39 | RABBIT_USERNAME = '' # 指定远程rabbitmq的用户名 40 | RABBIT_PWD = '' # 密码 41 | RABBIT_PORT = 5672 42 | RABBIT_V_HOST = '' 43 | -------------------------------------------------------------------------------- /atp-web-open/src/api/sys/user/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取用户列表 4 | */ 5 | 6 | export function getUserInfo(data) { 7 | return request({ 8 | url: '/atp/auto/user/detail', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | export function fetchUsertList(data) { 15 | return request({ 16 | url: '/atp/auto/user/list', 17 | method: 'post', 18 | data 19 | }) 20 | } 21 | 22 | // 新增用户 23 | export function addUser(data) { 24 | return request({ 25 | url: '/atp/auto/user/add', 26 | method: 'post', 27 | data 28 | }) 29 | } 30 | 31 | // 删除用户 32 | export function deleteUser(data) { 33 | return request({ 34 | url: '/atp/auto/user/delete', 35 | method: 'post', 36 | data 37 | }) 38 | } 39 | 40 | // 重置密码 41 | export function resetUserPassword(data) { 42 | return request({ 43 | url: '/atp/auto/user/resetPassword', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | // 修改密码 50 | export function changeUserPassword(data) { 51 | return request({ 52 | url: '/atp/auto/user/changePassword', 53 | method: 'post', 54 | data 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /atp-web-open/src/components/d2-page-cover/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | 28 | 50 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/comm_log.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import logging 4 | # from logging.handlers import WatchedFileHandler 5 | from atp.api.safe_file_handler import SafeFileHandler 6 | import time 7 | 8 | from atp.config.default import get_config 9 | 10 | config = get_config() 11 | 12 | log_path = config.LOG_PATH 13 | 14 | formatter = logging.Formatter('[%(filename)-12s]: [%(levelname)-6s] [%(asctime)s]: %(message)s') 15 | 16 | # watched_file_handler = WatchedFileHandler(log_path, encoding="utf-8") 17 | safe_file_handler = SafeFileHandler(log_path, encoding="utf-8") 18 | 19 | safe_file_handler.setFormatter(formatter) 20 | 21 | safe_file_handler.setLevel(logging.INFO) 22 | # watched_file_handler.setLevel(logging.INFO) 23 | 24 | logger = logging.getLogger(__name__) 25 | logger.setLevel(logging.INFO) 26 | # logger.setLevel(logging.INFO) 27 | 28 | logger.addHandler(safe_file_handler) 29 | 30 | if __name__ == "__main__": 31 | 32 | for i in range(10): 33 | logger.debug("This is debug information") 34 | logger.info("This is info information") 35 | logger.error("This is error information") 36 | time.sleep(.1) 37 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/catalog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Svg Vector Icons : http://www.sfont.cn 6 | 7 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/wechat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/resource-apiManage/system/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 新增工程 5 | */ 6 | 7 | export function addApiSystem(data) { 8 | return request({ 9 | url: '/atp/auto/apiSystem/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 编辑工程 17 | */ 18 | 19 | export function editApiSystem(data) { 20 | return request({ 21 | url: '/atp/auto/apiSystem/edit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 删除工程 29 | */ 30 | 31 | export function deleteApiSystem(data) { 32 | return request({ 33 | url: '/atp/auto/apiSystem/delete', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 根据公司id查询 公司下所有的系统 41 | */ 42 | 43 | export function queryByCompanyId(data) { 44 | return request({ 45 | url: '/atp/auto/apiSystem/queryByCompanyId', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | 51 | /** 52 | * 根据系统查询git分支号 53 | */ 54 | 55 | export function getGitBranchNamesBySystemId(data) { 56 | return request({ 57 | url: '/atp/auto/apiSystem/getGitBranchNamesBySystemId', 58 | method: 'post', 59 | data 60 | }) 61 | } 62 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/people.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/env.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | # import os 4 | import socket 5 | import re 6 | import platform 7 | import psutil 8 | 9 | # try: 10 | # import psutil 11 | # except Exception as e: 12 | # #pip.exe install psutil 13 | # print('psutil not found.pip install psutil') 14 | # 15 | 16 | 17 | # 从环境变量获取RUNNING_ENV 18 | # os_env = os.environ.get('ATP_AUTO_ENV') 19 | 20 | # 根据{ip:环境}映射关系获取RUNNING_ENV 21 | ip_env_map = { 22 | 'XX.XX.XX': 'DEV', 23 | 'XX.XX.XX': 'ALIUAT' 24 | } 25 | 26 | RUNNING_ENV = None 27 | current_ip = None 28 | 29 | for interface, snics in psutil.net_if_addrs().items(): 30 | for snic in snics: 31 | ## ipv4 32 | if snic.family == socket.AF_INET: 33 | for k, v in ip_env_map.items(): 34 | if re.search(k, snic.address): 35 | RUNNING_ENV = v 36 | current_ip = snic.address 37 | break 38 | 39 | if RUNNING_ENV: 40 | print("current IP:{0}, get ENV: {1}".format(current_ip, RUNNING_ENV)) 41 | else: 42 | RUNNING_ENV = 'DEV' 43 | print("current IP: {0}, not found in ip_env_map, use default ENV: {1}".format(current_ip, RUNNING_ENV)) 44 | 45 | # print(psutil.net_if_addrs().items()) 46 | 47 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/language.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/pandas_manager.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import pandas as pd 4 | from numpy import NaN 5 | from atp.utils.tools import json_dumps 6 | 7 | 8 | class PandasManager(object): 9 | 10 | def __int__(self): 11 | self.excel_path = None 12 | 13 | def base_testcase_excel_to_data(self, excel_path, column_list=None): 14 | if not column_list: 15 | column_list = [] 16 | xl = pd.ExcelFile(excel_path) 17 | 18 | data_list = [] 19 | 20 | for sheet_name in xl.sheet_names: 21 | df = xl.parse(sheet_name) 22 | 23 | sheet_data = [] 24 | 25 | for i in df.index.values: 26 | try: 27 | row_data = df.ix[i, column_list].fillna('').to_dict() 28 | except KeyError: 29 | row_data = None 30 | if row_data: 31 | sheet_data.append(row_data) 32 | 33 | data_list.append({sheet_name: sheet_data}) 34 | 35 | return data_list 36 | 37 | 38 | if __name__ == '__main__': 39 | example_excel = r'业务用例.xls' 40 | pdm = PandasManager() 41 | data = pdm.base_testcase_excel_to_data(example_excel, ['模块', '用例标题', '前置条件', '操作步骤', '预期结果', '备注']) 42 | print(data) 43 | -------------------------------------------------------------------------------- /atp-web-open/src/main.js: -------------------------------------------------------------------------------- 1 | // polyfill 2 | import 'babel-polyfill' 3 | // Vue 4 | import Vue from 'vue' 5 | import App from './App' 6 | // store 7 | import store from '@/store/index' 8 | // 核心插件 9 | import '@/icons' 10 | import d2Admin from '@/plugin/d2admin' 11 | // 菜单和路由设置 12 | import router from './router' 13 | import { menuHeader, menuAside } from '@/menu' 14 | import { frameInRoutes } from '@/router/routes' 15 | // 右键菜单插件 16 | import contentmenu from 'v-contextmenu' 17 | import 'v-contextmenu/dist/index.css' 18 | Vue.use(contentmenu) 19 | // 核心插件 20 | Vue.use(d2Admin) 21 | 22 | new Vue({ 23 | router, 24 | store, 25 | render: h => h(App), 26 | created() { 27 | // 处理路由 得到每一级的路由设置 28 | this.$store.commit('d2admin/page/init', frameInRoutes) 29 | // 设置顶栏菜单 30 | this.$store.commit('d2admin/menu/headerSet', menuHeader) 31 | }, 32 | mounted() { 33 | // 用户登录后从数据库加载一系列的设置 34 | this.$store.commit('d2admin/account/load') 35 | // 获取并记录用户 UA 36 | this.$store.commit('d2admin/ua/get') 37 | }, 38 | watch: { 39 | // 监听路由 控制侧边栏显示 40 | '$route.matched'(val) { 41 | const _side = menuAside.filter(menu => menu.path === val[0].path) 42 | this.$store.commit('d2admin/menu/asideSet', _side.length > 0 ? _side[0].children : []) 43 | } 44 | } 45 | }).$mount('#app') 46 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/components/menu-header/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![ATP图标](https://github.com/ooqitech/ATP/blob/master/images/atp2.png) 2 | 3 | 4 | 5 | ## **ATP简介** 6 | - ATP是基于python开发的测试服务平台,为公司测试团队提供各类接口的测试入口、测试数据构造,mock第三方测试平台。 7 | - ATP平台采用Vue.js+Flask的前后端分离的架构,数据存储用到了MySQL和Redis。 8 | - ATP的优势是它可以统一接口测试方法,统一管理所有接口测试用例,统一规划测试回归范围,可操作界面,降低全员的学习成本。 9 | 10 | ## **ATP产品价值** 11 | - 降低工具开发成本 12 | - 降低用例维护成本 13 | - 降低bug定位成本 14 | - 降低工具学习成本 15 | - 提高接口测试效率 16 | 17 | ## **ATP优势** 18 | - 一套平台的环境可对接测试多套业务系统的测试环 19 | - 多套测试环境共用一套接口测试用例 20 | - 可测试全链路接口,符合业务场景需求 21 | - 平台内的公共变量可用于所有业务系统用例 22 | 23 | ## **ATP工程模块说明** 24 | [工程说明](https://github.com/ooqitech/ATP/wiki/projectSpecification) 25 | - ATP-Web前端页面工程使用Vue.js和Element-ui,用到Element-ui是因为它基于Vue2.0,有丰富的成熟组件拿来即用,非常适合网站页面快速成型。 26 | - ATP-Core后端核心服务使用Flask作为服务端提供纯RESTful接口,选用Flask同样是因为Flask框架现在非常成熟,而且不重,也有丰富的第三方模块,生态良好。 27 | 28 | ## **ATP功能模块说明** 29 | [模块说明](https://github.com/ooqitech/ATP/wiki/function) 30 | - 环境配置:配置多套测试环境,分离测试用例和测试环境,可以保证一套用例多套环境使用。 31 | - 变量配置:公共变量和用例变量配置,公共变量可以使用在所有接口里,用例变量只能用在当前用例中。 32 | - 用例管理:设计用例,包括用例变量、前置用例、接口基本信息、入参、检查点。 33 | - 用例执行:可以选择指定环境执行用例。 34 | - 日志推送:多用于调试用例,一般用例执行失败原因可在平台日志中打印,无需多翻阅业务系统日志。 35 | 36 | ## **ATP主要页面介绍** 37 | 38 | [ATP主要页面介绍](https://github.com/ooqitech/ATP/wiki/functionForATP) 39 | 40 | ## **ATP快速部署文档** 41 | 42 | [快速部署文档](https://github.com/ooqitech/ATP/wiki/deployment) 43 | 44 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/httprunner/exceptions.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | from atp.httprunner.compat import JSONDecodeError, FileNotFoundError 4 | 5 | """ failure type exceptions 6 | these exceptions will mark test as failure 7 | """ 8 | 9 | class MyBaseFailure(Exception): 10 | pass 11 | 12 | class ValidationFailure(MyBaseFailure): 13 | pass 14 | 15 | class ExtractFailure(MyBaseFailure): 16 | pass 17 | 18 | class SetupHooksFailure(MyBaseFailure): 19 | pass 20 | 21 | class TeardownHooksFailure(MyBaseFailure): 22 | pass 23 | 24 | class RequestFailure(MyBaseFailure): 25 | pass 26 | 27 | 28 | """ error type exceptions 29 | these exceptions will mark test as error 30 | """ 31 | 32 | class MyBaseError(Exception): 33 | pass 34 | 35 | class FileFormatError(MyBaseError): 36 | pass 37 | 38 | class ParamsError(MyBaseError): 39 | pass 40 | 41 | class NotFoundError(MyBaseFailure): 42 | pass 43 | 44 | class FileNotFound(FileNotFoundError, NotFoundError): 45 | pass 46 | 47 | class FunctionNotFound(NotFoundError): 48 | pass 49 | 50 | class VariableNotFound(NotFoundError): 51 | pass 52 | 53 | class ApiNotFound(NotFoundError): 54 | pass 55 | 56 | class TestcaseNotFound(NotFoundError): 57 | pass 58 | 59 | class CustomFuncRunError(MyBaseFailure): 60 | pass 61 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/httprunner/compat.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | """ 4 | httprunner.compat 5 | ~~~~~~~~~~~~~~~~~ 6 | 7 | This module handles import compatibility issues between Python 2 and 8 | Python 3. 9 | """ 10 | 11 | try: 12 | import simplejson as json 13 | except ImportError: 14 | import json 15 | 16 | import sys 17 | 18 | # ------- 19 | # Pythons 20 | # ------- 21 | 22 | # Syntax sugar. 23 | _ver = sys.version_info 24 | 25 | #: Python 2.x? 26 | is_py2 = (_ver[0] == 2) 27 | 28 | #: Python 3.x? 29 | is_py3 = (_ver[0] == 3) 30 | 31 | 32 | # --------- 33 | # Specifics 34 | # --------- 35 | 36 | try: 37 | JSONDecodeError = json.JSONDecodeError 38 | except AttributeError: 39 | JSONDecodeError = ValueError 40 | 41 | if is_py2: 42 | from urllib3.packages.ordered_dict import OrderedDict 43 | 44 | builtin_str = str 45 | bytes = str 46 | str = unicode 47 | basestring = basestring 48 | numeric_types = (int, long, float) 49 | integer_types = (int, long) 50 | 51 | FileNotFoundError = IOError 52 | 53 | elif is_py3: 54 | from collections import OrderedDict 55 | 56 | builtin_str = str 57 | str = str 58 | bytes = bytes 59 | basestring = (str, bytes) 60 | numeric_types = (int, float) 61 | integer_types = (int,) 62 | 63 | FileNotFoundError = FileNotFoundError 64 | -------------------------------------------------------------------------------- /atp-auto-core-open/gunicorn/gunicorn_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import sys 4 | import os 5 | # import multiprocessing 6 | import platform 7 | 8 | # __file__:当前文件路径 9 | # os.path.dirname(file): 某个文件所在的目录路径 10 | # os.path.join(a, b, c,....): 路径构造 a/b/c 11 | # os.path.abspath(path): 将path从相对路径转成绝对路径 12 | # os.pardir: Linux下相当于"../" 13 | parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) 14 | 15 | # 最好不要写死,用os获得相对于此配置文件的app所在的路径 16 | path_of_current_dir = parent_dir 17 | 18 | # print path_of_current_dir 19 | sys.path.insert(0, path_of_current_dir) 20 | 21 | worker_class = 'gevent' 22 | 23 | # workers也要根据实际情况修改 24 | workers = 2 # multiprocessing.cpu_count() * 2 + 1 25 | 26 | chdir = path_of_current_dir 27 | 28 | worker_connections = 1000 29 | timeout = 30 # 超时时间 30 | max_requests = 2000 # 到达max_requests时 worker会在处理好这个请求后自动重启 31 | graceful_timeout = 30 32 | 33 | loglevel = 'info' 34 | 35 | reload = True 36 | debug = False 37 | 38 | bind = "%s:%s" % ("0.0.0.0", 7000) 39 | 40 | access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(U)s %(q)s %(s)s %(b)s "%(f)s" "%(a)s" %(D)s %(T)s %(i)s %(o)s %(e)s' 41 | 42 | 43 | errorlog = '/usr/local/src/logs/atp-auto-core/gunicorn_auto_error.log' 44 | accesslog = '/usr/local/src/logs/atp-auto-core/gunicorn_auto_access.log' 45 | 46 | capture_output = True 47 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/utils/cache_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | class CacheData(object): 5 | def __init__(self): 6 | if not hasattr(self, "USERNAME_NICKNAME_DIC"): 7 | from atp.api.mysql_manager import UserManager 8 | self.USERNAME_NICKNAME_DIC = {row[0]: row[1] for row in UserManager.get_all_username_nickname()} 9 | 10 | if not hasattr(self, "TAG_BASE_MAP"): 11 | from atp.api.mysql_manager import TestcaseTagManager 12 | tag_objs = TestcaseTagManager.query_testcase_tag() 13 | self.TAG_BASE_MAP = {} 14 | for tag_obj in tag_objs: 15 | if tag_obj.tag_category not in self.TAG_BASE_MAP: 16 | self.TAG_BASE_MAP[tag_obj.tag_category] = [{"tagId": tag_obj.id, "tagName": tag_obj.tag_name}] 17 | else: 18 | self.TAG_BASE_MAP[tag_obj.tag_category].append({"tagId": tag_obj.id, "tagName": tag_obj.tag_name}) 19 | 20 | def __new__(cls, *args, **kwargs): 21 | if not hasattr(CacheData, "_instance"): # 反射 22 | CacheData._instance = object.__new__(cls) 23 | return CacheData._instance 24 | 25 | def get_username_nickname_dic(self): 26 | return self.USERNAME_NICKNAME_DIC 27 | 28 | def get_tag_base_map(self): 29 | return self.TAG_BASE_MAP 30 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/resource-apiManage/api/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 新增接口 4 | */ 5 | 6 | export function addApi(data) { 7 | return request({ 8 | url: '/atp/auto/apiIntf/add', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 编辑接口 16 | */ 17 | 18 | export function editApi(data) { 19 | return request({ 20 | url: '/atp/auto/apiIntf/edit', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 删除接口 28 | */ 29 | 30 | export function deleteApi(data) { 31 | return request({ 32 | url: '/atp/auto/apiIntf/delete', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | 38 | /** 39 | * 接口详情 40 | */ 41 | 42 | export function queryApiDetail(data) { 43 | return request({ 44 | url: '/atp/auto/apiIntf/detail', 45 | method: 'post', 46 | data 47 | }) 48 | } 49 | 50 | /** 51 | * 根据接口id 查询接口下所有的用例 52 | */ 53 | 54 | export function queryCaseByIntfId(data) { 55 | return request({ 56 | url: '/atp/auto/apiTestcase/queryByIntfId', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * 根据工程id 查询工程下所有的接口 64 | */ 65 | 66 | export function queryByProjectId(data) { 67 | return request({ 68 | url: '/atp/auto/apiIntf/queryBySystemId', 69 | method: 'post', 70 | data 71 | }) 72 | } 73 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/components/contextmenu/components/contentmenuList/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 30 | 31 | 49 | -------------------------------------------------------------------------------- /atp-auto-core-open/gunicorn/gunicorn_config_for_socket.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import sys 4 | import os 5 | # import multiprocessing 6 | import platform 7 | 8 | # __file__:当前文件路径 9 | # os.path.dirname(file): 某个文件所在的目录路径 10 | # os.path.join(a, b, c,....): 路径构造 a/b/c 11 | # os.path.abspath(path): 将path从相对路径转成绝对路径 12 | # os.pardir: Linux下相当于"../" 13 | parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) 14 | 15 | # 最好不要写死,用os获得相对于此配置文件的app所在的路径 16 | path_of_current_dir = parent_dir 17 | 18 | # print path_of_current_dir 19 | sys.path.insert(0, path_of_current_dir) 20 | 21 | worker_class = 'gevent' 22 | 23 | # workers也要根据实际情况修改 24 | workers = 1 # multiprocessing.cpu_count() * 2 + 1 25 | 26 | chdir = path_of_current_dir 27 | 28 | worker_connections = 1000 29 | timeout = 30 # 超时时间 30 | max_requests = 2000 # 到达max_requests时 worker会在处理好这个请求后自动重启 31 | graceful_timeout = 30 32 | 33 | loglevel = 'info' 34 | 35 | reload = True 36 | debug = False 37 | 38 | bind = "%s:%s" % ("0.0.0.0", 7500) 39 | 40 | access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(U)s %(q)s %(s)s %(b)s "%(f)s" "%(a)s" %(D)s %(T)s %(i)s %(o)s %(e)s' 41 | 42 | 43 | errorlog = '/usr/local/src/logs/atp-auto-core/gunicorn_socket_error.log' 44 | accesslog = '/usr/local/src/logs/atp-auto-core/gunicorn_socket_access.log' 45 | 46 | capture_output = True 47 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testcase-testCaseConfig/testplan/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 添加测试计划 5 | */ 6 | 7 | export function addTestPlan(data) { 8 | return request({ 9 | url: '/atp/auto/testPlan/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 测试计划列表 17 | */ 18 | export function fetchPlanList(data) { 19 | return request({ 20 | url: '/atp/auto/testPlan/list', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 测试计划详情 28 | */ 29 | 30 | export function queryTestPlan(data) { 31 | return request({ 32 | url: '/atp/auto/testPlan/detail', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | 38 | /** 39 | * 删除测试计划 40 | */ 41 | 42 | export function deleteTestPlan(data) { 43 | return request({ 44 | url: '/atp/auto/testPlan/delete', 45 | method: 'post', 46 | data 47 | }) 48 | } 49 | 50 | /** 51 | * 编辑测试计划 52 | */ 53 | 54 | export function editTestPlan(data) { 55 | return request({ 56 | url: '/atp/auto/testPlan/edit', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * 查询测试计划最近一次运行报告ID 64 | */ 65 | export function queryTestPlanRecentReportId(data) { 66 | return request({ 67 | url: '/atp/auto/testPlan/queryRecentReportId', 68 | method: 'post', 69 | data 70 | }) 71 | } 72 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testcase-testCaseConfig/testsuite/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 添加测试集 5 | */ 6 | 7 | export function addSuite(data) { 8 | return request({ 9 | url: '/atp/auto/testsuite/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 修改测试集 17 | */ 18 | 19 | export function editSuite(data) { 20 | return request({ 21 | url: '/atp/auto/testsuite/edit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 删除测试集 29 | */ 30 | 31 | export function deleteSuite(data) { 32 | return request({ 33 | url: '/atp/auto/testsuite/delete', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 查询测试集详情 41 | */ 42 | 43 | export function querySuite(data) { 44 | return request({ 45 | url: '/atp/auto/testsuite/detail', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | 51 | /** 52 | * 查询某个项目下所有用例集 53 | */ 54 | 55 | export function listByProjectId(data) { 56 | return request({ 57 | url: '/atp/auto/testsuite/listByProjectId', 58 | method: 'post', 59 | data 60 | }) 61 | } 62 | 63 | /** 64 | * 移动测试集 65 | */ 66 | 67 | export function changeModuleParent(data) { 68 | return request({ 69 | url: '/atp/auto/testsuite/changeParent', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testcase-testCaseConfig/pageobject/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 添加页面 5 | */ 6 | 7 | export function addPage(data) { 8 | return request({ 9 | url: '/atp/auto/page/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 添加页面对象 17 | */ 18 | 19 | export function addPageElement(data) { 20 | return request({ 21 | url: '/atp/auto/pageobject/add', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 编辑页面对象 29 | */ 30 | 31 | export function editPageElement(data) { 32 | return request({ 33 | url: '/atp/auto/pageobject/edit', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 删除页面对象 41 | */ 42 | 43 | export function deletePageElement(data) { 44 | return request({ 45 | url: '/atp/auto/pageobject/delete', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | 51 | /** 52 | * 页面id,查询所以页面元素 53 | */ 54 | 55 | export function fetchPageElements(data) { 56 | return request({ 57 | url: '/atp/auto/pageobject/queryByPageId', 58 | method: 'post', 59 | data 60 | }) 61 | } 62 | 63 | /** 64 | * 系统id:查询所有页面 65 | */ 66 | 67 | export function fetchPageList(data) { 68 | return request({ 69 | url: '/atp/auto/page/pageList', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/components/components/menu-sub/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 43 | -------------------------------------------------------------------------------- /atp-web-open/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | 4 | import util from '@/libs/util.js' 5 | 6 | // 进度条 7 | import NProgress from 'nprogress' 8 | import 'nprogress/nprogress.css' 9 | 10 | // 路由数据 11 | import routes from './routes' 12 | 13 | Vue.use(VueRouter) 14 | 15 | // 导出路由 在 main.js 里使用 16 | const router = new VueRouter({ 17 | routes 18 | }) 19 | 20 | /** 21 | * 路由拦截 22 | * 权限验证 23 | */ 24 | router.beforeEach((to, from, next) => { 25 | // 进度条 26 | NProgress.start() 27 | // 验证当前路由所有的匹配中是否需要有登录验证的 28 | if (to.matched.some(r => r.meta.requiresAuth)) { 29 | // 这里暂时将cookie里是否存有token作为验证是否登录的条件 30 | const token = util.cookies.get('token') 31 | if (token && token !== 'undefined') { 32 | next() 33 | } else { 34 | // 将当前预计打开的页面完整地址临时存储 登录后继续跳转 35 | // 这个 cookie(redirect) 会在登录后自动删除 36 | util.cookies.set('redirect', to.fullPath) 37 | // 没有登录的时候跳转到登录界面 38 | next({ 39 | name: 'login' 40 | }) 41 | } 42 | } else { 43 | // 不需要身份校验 直接通过 44 | next() 45 | } 46 | }) 47 | 48 | router.afterEach(to => { 49 | // 进度条 50 | NProgress.done() 51 | // 需要的信息 52 | const app = router.app 53 | const { name, params, query } = to 54 | // 多页控制 打开新的页面 55 | app.$store.commit('d2admin/page/open', { name, params, query }) 56 | // 更改标题 57 | util.title(to.meta.title) 58 | }) 59 | 60 | export default router 61 | -------------------------------------------------------------------------------- /atp-web-open/src/api/tools/tool-fareIncreaseService/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取加价策略数据 4 | */ 5 | 6 | export function queryFareIncreaseServiceConfig(data) { 7 | return request({ 8 | url: '/atp/qa/queryFareIncreaseServiceConfig', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 获取加价策略字段字典 16 | */ 17 | 18 | export function getFareIncreaseServiceMappingList(data) { 19 | return request({ 20 | url: '/atp/qa/getFareIncreaseServiceMappingList', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 配置现金贷加价策略 28 | */ 29 | 30 | export function setCashLoanConfig(data) { 31 | return request({ 32 | url: '/atp/qa/setCashLoanConfig', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | 38 | /** 39 | * 配置大额首单现金贷加价策略 40 | */ 41 | 42 | export function setBigFirstOrderConfig(data) { 43 | return request({ 44 | url: '/atp/qa/setBigFirstOrderConfig', 45 | method: 'post', 46 | data 47 | }) 48 | } 49 | 50 | /** 51 | * 配置不等贷加价策略 52 | */ 53 | 54 | export function setNoWaitLoanConfig(data) { 55 | return request({ 56 | url: '/atp/qa/setNoWaitLoanConfig', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * 配置医美加价策略 64 | */ 65 | 66 | export function setMedicalConfig(data) { 67 | return request({ 68 | url: '/atp/qa/setMedicalConfig', 69 | method: 'post', 70 | data 71 | }) 72 | } 73 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/404.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/zip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/resource-publicVariable/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 获取公共变量列表 5 | */ 6 | 7 | export function fetchPublicvariableList(data) { 8 | return request({ 9 | url: '/atp/auto/apiPublicVariable/list', 10 | method: 'get', 11 | params: data 12 | }) 13 | } 14 | 15 | /** 16 | * 增加公共变量列表 17 | */ 18 | 19 | export function addPublicvariable(data) { 20 | return request({ 21 | url: '/atp/auto/apiPublicVariable/addVariable', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 获取已支持的变量列表 29 | */ 30 | 31 | export function querySupportPubVariables(data) { 32 | return request({ 33 | url: '/atp/auto/apiPublicVariable/querySupportPubVariables', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | /** 39 | * 编辑公共变量 40 | */ 41 | 42 | export function editPublicvariable(data) { 43 | return request({ 44 | url: '/atp/auto/apiPublicVariable/edit', 45 | method: 'post', 46 | data 47 | }) 48 | } 49 | 50 | /** 51 | * 删除公共变量 52 | */ 53 | export function deleteVariable(data) { 54 | return request({ 55 | url: '/atp/auto/apiPublicVariable/delete', 56 | method: 'post', 57 | data 58 | }) 59 | } 60 | 61 | /** 62 | * 根据用例id查询用例(包含前置)的公共变量列表 63 | */ 64 | export function queryPubVarsByTcList(data) { 65 | return request({ 66 | url: '/atp/auto/apiPublicVariable/queryPubVariablesByTestcaseList', 67 | method: 'post', 68 | data 69 | }) 70 | } 71 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/views/run_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import json 4 | from flask import request 5 | from flask import Blueprint 6 | from flask_restful import Resource 7 | from atp.engine.run_uitest import run_uitest 8 | from atp.views.wrappers import timer, developer_check, login_check 9 | from atp.utils.common import get_request_json, make_response 10 | from atp.engine.exceptions import LoadCaseError, RunCaseError, NoSuchElementError 11 | from atp.api.redis_api import RedisManager 12 | 13 | redis = RedisManager() 14 | run_ui = Blueprint('run_ui_interface', __name__) 15 | 16 | 17 | class RunUiTestCase(Resource): 18 | def __init__(self): 19 | self.data = get_request_json() 20 | 21 | @timer 22 | @developer_check 23 | def post(self): 24 | try: 25 | testcase_id_list = self.data.pop("testaCases") 26 | remote_url = self.data.pop("remoteUrl", None) 27 | local_browser = self.data.pop("localBrowser",None) 28 | except KeyError: 29 | return make_response({"code": "100", "desc": "入参校验错误"}) 30 | try: 31 | reportUrl = run_uitest(testcase_id_list, remote_url,local_browser) 32 | except LoadCaseError: 33 | return make_response({"code": "201", "desc": "组装用例时出错"}) 34 | except RunCaseError: 35 | return make_response({"code": "200", "desc": "运行UI用例时出错,请检查运行环境"}) 36 | return make_response({"code": "000", "desc": "运行成功", "reportUrl": reportUrl}) 37 | -------------------------------------------------------------------------------- /atp-auto-core-open/requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==0.9.9 2 | amqp==2.4.2 3 | aniso8601==3.0.2 4 | billiard==3.6.0.0 5 | celery==4.3.0 6 | certifi==2018.4.16 7 | cffi==1.11.5 8 | chardet==3.0.4 9 | click==6.7 10 | colorama==0.3.9 11 | colorlog==3.1.4 12 | decorator==4.3.0 13 | docopt==0.6.2 14 | et-xmlfile==1.0.1 15 | fire==0.1.3 16 | Flask==1.0.2 17 | Flask-Cache==0.13.1 18 | Flask-Migrate==2.2.0 19 | Flask-RESTful==0.3.6 20 | Flask-Script==2.0.6 21 | Flask-SocketIO==3.0.2 22 | Flask-SQLAlchemy==2.3.2 23 | flower==0.9.3 24 | gevent==1.4.0 25 | greenlet==0.4.15 26 | har2case==0.1.8 27 | humanize==0.5.1 28 | idna==2.7 29 | itsdangerous==0.24 30 | jdcal==1.4 31 | Jinja2==2.10.1 32 | kombu==4.5.0 33 | locustio==0.9.0 34 | logzero==1.5.0 35 | Mako==1.0.7 36 | MarkupSafe==1.0 37 | msgpack==0.6.0 38 | numpy==1.16.3 39 | openpyxl==2.5.12 40 | pandas==0.24.2 41 | paramiko==2.4.2 42 | pika==1.1.0 43 | progress==1.4 44 | py==1.7.0 45 | pycparser==2.19 46 | PyMySQL==0.8.1 47 | python-crontab==2.3.5 48 | python-dateutil==2.7.3 49 | python-editor==1.0.3 50 | python-engineio==3.9.0 51 | python-gitlab==1.2.0 52 | python-socketio==2.0.0 53 | pytz==2018.4 54 | PyYAML==4.2 55 | pyzmq==17.1.2 56 | redis==3.2.1 57 | requests==2.20.0 58 | requests-toolbelt==0.8.0 59 | retry==0.9.2 60 | selenium==3.141.0 61 | six==1.11.0 62 | SQLAlchemy==1.3.0 63 | sqlparse==0.3.0 64 | uiautomator2==0.2.2 65 | urllib3==1.23 66 | vine==1.3.0 67 | Werkzeug==0.15.3 68 | whichcraft==0.5.2 69 | XMind==1.2.0 70 | aliyun-python-sdk-ons==3.1.2 71 | aliyunsdkcore==1.0.3 72 | psutil==5.6.7 73 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testcase-testCaseConfig/module/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 添加模块 5 | */ 6 | 7 | export function addModule(data) { 8 | return request({ 9 | url: '/atp/auto/module/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 修改模块 17 | */ 18 | 19 | export function editModule(data) { 20 | return request({ 21 | url: '/atp/auto/module/edit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 删除模块 29 | */ 30 | 31 | export function deleteModule(data) { 32 | return request({ 33 | url: '/atp/auto/module/delete', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 根据系统ID查询模块 41 | */ 42 | 43 | export function queryBySystemId(data) { 44 | return request({ 45 | url: '/atp/auto/module/queryBySystemId', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | 51 | /** 52 | * 导出模块的用例生成xmind 53 | */ 54 | 55 | export function exportMoudleCase(data) { 56 | return request({ 57 | url: '/atp/auto/download/xmindApi', 58 | method: 'post', 59 | data 60 | }) 61 | } 62 | 63 | /** 64 | * 查询模块 65 | */ 66 | 67 | export function queryModule(data) { 68 | return request({ 69 | url: '/atp/auto/module/detail', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * 移动模块 77 | */ 78 | 79 | export function changeSystemParent(data) { 80 | return request({ 81 | url: '/atp/auto/module/changeParent', 82 | method: 'post', 83 | data 84 | }) 85 | } 86 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/bug.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/mock/mock-config/scene/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | 3 | /** 4 | * 新增mock场景 5 | */ 6 | 7 | export function addMockScene(data) { 8 | return request({ 9 | url: '/atp/mock/config/scene/add', 10 | method: 'post', 11 | data 12 | }) 13 | } 14 | 15 | /** 16 | * 修改mock场景 17 | */ 18 | 19 | export function editMockScene(data) { 20 | return request({ 21 | url: '/atp/mock/config/scene/edit', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | /** 28 | * 删除已配置的mock接口 29 | */ 30 | 31 | export function deleteMock(data) { 32 | return request({ 33 | url: '/atp/mock/config/scene/delete', 34 | method: 'post', 35 | data 36 | }) 37 | } 38 | 39 | /** 40 | * 查询已配置的mock接口详情 41 | */ 42 | 43 | export function queryMockDetails(data) { 44 | return request({ 45 | url: '/atp/mock/config/scene/query', 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | 51 | /** 52 | * 测试已配置的mock接口 53 | */ 54 | 55 | export function testMockPost(data) { 56 | let body = data.requestBody 57 | let headers = { 58 | 'Content-Type': data.contentType, 59 | 'Access-Control-Allow-Origin': '*' 60 | } 61 | return request({ 62 | url: `/mock/service/${data.projectName}/${data.interfaceName}`, 63 | method: 'post', 64 | data: body, 65 | headers 66 | }) 67 | } 68 | 69 | export function testMockGet(data) { 70 | let url = data.requestBody 71 | return request({ 72 | url: `/mock/service/${data.projectName}/${data.interfaceName}` + '?' + url, 73 | method: 'get' 74 | }) 75 | } 76 | -------------------------------------------------------------------------------- /atp-web-open/src/pages/mock/mock-log/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 46 | 53 | -------------------------------------------------------------------------------- /atp-web-open/src/pages/qadata/form-bugDataStatistics/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 49 | 56 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/ssh_executor.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import os 3 | from atp.api.comm_log import logger 4 | try: 5 | import paramiko 6 | except ImportError: 7 | logger.error("ImportError: No module named 'paramiko'") 8 | 9 | 10 | def server_upload_file(ssh_connect, local_path, remote_path): 11 | """ 12 | 向指定服务器上传文件 13 | :param ssh_connect: 14 | :param local_path: 15 | :param remote_path: 16 | :return: 17 | """ 18 | if isinstance(ssh_connect, str): 19 | ssh_info = eval(ssh_connect) 20 | else: 21 | ssh_info = ssh_connect 22 | # 实例化Transport 23 | ssh = paramiko.Transport(ssh_info[0], ssh_info[1]) 24 | # 建立连接 25 | ssh.connect(username=ssh_info[2], password=ssh_info[3]) 26 | # 实例化一个sftp对象 27 | transport = paramiko.SFTPClient.from_transport(ssh) 28 | try: 29 | if os.path.isdir(local_path): # 判断本地参数是目录还是文件 30 | local_path_list = os.listdir(local_path) 31 | for f in local_path_list: # 遍历本地目录 32 | transport.put(os.path.join(local_path + f), os.path.join(remote_path + f)) # 上传目录中的文件 33 | logger.debug("上传{0}目录文件成功:{1}".format(local_path, local_path_list)) 34 | else: 35 | transport.put(local_path, remote_path) # 上传文件 36 | logger.debug("上传文件成功:{}".format(local_path)) 37 | except Exception as e: 38 | logger.debug('上传文件异常:', e) 39 | ssh.close() 40 | 41 | if __name__ == '__main__': 42 | server_upload_file('[\"**.**.**.**\",22,\"user\",\"password\"]', 'E:\\test\\settings.xml', '/home/admin/settings.xml') 43 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/views/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | from .env import env, Env 4 | from .project import project, Project 5 | # from .system import system, System 6 | # from .module import module, Module 7 | # from .testsuite import testsuite, Testsuite 8 | from .testcase import testcase, Testcase 9 | # from .run import run, Run 10 | # from .publicvariables import publicvariable, PublicVariable 11 | from .file import file, File 12 | from .support import support, Support 13 | # from .test_plan import test_plan, TestPlan 14 | # from .report import report, Report 15 | from .user import user, User 16 | from .stat import stat, Stat 17 | from .run_ui import run_ui, RunUiTestCase 18 | from .tag import tag, Tag 19 | from .download import download, Download 20 | from .ui_page import page,Page 21 | from .ui_pageobject import pageobject,PageObject 22 | from .ui_testcase import ui_testcase,UiTestCase 23 | from .api_company import api_company, ApiCompany 24 | from .api_system import api_system, ApiSystem 25 | from .api_intf import api_intf, ApiIntf 26 | from .api_testcase import api_testcase, ApiTestcase 27 | from .api_project import api_project, ApiProject 28 | from .api_run import api_run, ApiRun 29 | from .api_public_variable import api_public_variable, ApiPublicVariable 30 | from .api_report import api_report, ApiReport 31 | from .api_product_line import api_product_line, ApiProductLine 32 | from .api_testcase_main import api_testcase_main, ApiTestcaseMain 33 | from .api_task import api_task, ApiTask 34 | from .call_back import call_back, CallBack 35 | from .api_push_log import api_push_log, ApiPushLog 36 | -------------------------------------------------------------------------------- /atp-web-open/src/layout/header-aside/components/contextmenu/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 57 | 58 | 69 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testcase-apiManage/support/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 查询已支持的前置操作hooks函数 4 | */ 5 | 6 | export function queryCustomSetupHooks(data) { 7 | return request({ 8 | url: '/atp/auto/support/queryCustomSetupHooks', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 查询已支持的参数化变量类型 16 | */ 17 | 18 | export function querySupportVariableTypes(data) { 19 | return request({ 20 | url: '/atp/auto/support/querySupportVariableTypes', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 查询已支持的自定义变量函数 28 | */ 29 | 30 | export function queryCustomFunctions(data) { 31 | return request({ 32 | url: '/atp/auto/support/queryCustomFunctions', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | 38 | /** 39 | * 查询已支持的加签函数 40 | */ 41 | 42 | export function querySignFunctions(data) { 43 | return request({ 44 | url: '/atp/auto/support/querySignFunctions', 45 | method: 'post', 46 | data 47 | }) 48 | } 49 | 50 | /** 51 | * 查询已支持的断言类型 52 | */ 53 | 54 | export function queryCustomComparators(data) { 55 | return request({ 56 | url: '/atp/auto/support/queryCustomComparators', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * 查询已支持的后置操作hooks函数 64 | */ 65 | 66 | export function queryCustomTeardownHooks(data) { 67 | return request({ 68 | url: '/atp/auto/support/queryCustomTeardownHooks', 69 | method: 'post', 70 | data 71 | }) 72 | } 73 | 74 | /** 75 | * 标签列表 76 | */ 77 | 78 | export function queryTagList(data) { 79 | return request({ 80 | url: '/atp/auto/tag/list', 81 | method: 'post', 82 | data 83 | }) 84 | } 85 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/fulllinecase.js: -------------------------------------------------------------------------------- 1 | export default { 2 | namespaced: true, 3 | state: { 4 | // 全链路用例列表数据 5 | caseTable: { 6 | productLineId: '', 7 | testcaseId: '', 8 | id: 0 9 | }, 10 | // 支持函数表数据 11 | supportTable: { 12 | supportSetupFuncs: [], 13 | supportVariableType: [], 14 | customVariableFunctions: [], 15 | supportSignFuncs: [], 16 | supportCustomComparators: [], 17 | supportTeardownFuncs: [] 18 | }, 19 | // 是否点击添加测试用例菜单 20 | addCaseVisible: false, 21 | baseTable: { 22 | companyId: 1 23 | } 24 | 25 | }, 26 | getters: { 27 | }, 28 | // 用例树上切换不同节点,展示相应的用例数据 29 | mutations: { 30 | changeFullLineCaseTable(state, caseTableInfo) { 31 | state.caseTable = { 32 | productLineId: caseTableInfo.productLineId, 33 | testcaseId: caseTableInfo.testcaseId, 34 | id: caseTableInfo.id 35 | } 36 | }, 37 | changeSupportTable(state, supportTableInfo) { 38 | state.supportTable = { 39 | supportSetupFuncs: supportTableInfo.supportSetupFuncs, 40 | supportVariableType: supportTableInfo.supportVariableType, 41 | customVariableFunctions: supportTableInfo.customVariableFunctions, 42 | supportSignFuncs: supportTableInfo.supportSignFuncs, 43 | supportCustomComparators: supportTableInfo.supportCustomComparators, 44 | supportTeardownFuncs: supportTableInfo.supportTeardownFuncs 45 | } 46 | }, 47 | addCase(state, addCaseVisible) { 48 | state.addCaseVisible = addCaseVisible 49 | }, 50 | 51 | changeCompanyId(state, companyId) { 52 | state.baseTable = { 53 | companyId: companyId 54 | } 55 | } 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/views/ui_page.py: -------------------------------------------------------------------------------- 1 | 2 | from flask import Blueprint 3 | from flask_restful import Resource 4 | from atp.utils.common import get_request_json, make_response, username_to_nickname 5 | from atp.api.mysql_manager import UICasePageInfoManager,UICasePageObjectInfoManage 6 | page = Blueprint('page_interface', __name__) 7 | 8 | 9 | class Page(Resource): 10 | def __init__(self): 11 | self.upim = UICasePageInfoManager() 12 | self.data = get_request_json() 13 | 14 | def post(self,action): 15 | if action == 'add': 16 | return self.add_page() 17 | if action == 'pageList': 18 | return self.pagelist_by_systemid() 19 | 20 | def add_page(self): 21 | try: 22 | page_name = self.data.pop("pageName") 23 | system_id = self.data.pop("systemId") 24 | simple_Desc = self.data.pop("simpleDesc", None) 25 | 26 | except KeyError: 27 | return make_response({"code": "100", "desc": "入参校验失败"}) 28 | self.upim.insert_ui_page(page_name=page_name,simple_desc=simple_Desc,system_id=system_id ) 29 | return make_response({"code": "000", "desc": "新增page{}成功".format(page_name)}) 30 | 31 | def pagelist_by_systemid(self): 32 | try: 33 | system_id = self.data.pop("systemId") 34 | except KeyError: 35 | return make_response({"code": "100", "desc": "入参校验失败"}) 36 | objs = self.upim.query_ui_pages(system_id=system_id) 37 | page_list = [] 38 | for obj in objs: 39 | page_dict={ 40 | "id":obj.id, 41 | "pageName":obj.page_name 42 | } 43 | page_list.append(page_dict) 44 | return make_response({"code": "000", "desc": page_list}) 45 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "atp-web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "master": "vue-cli-service build --mode master", 8 | "test": "vue-cli-service build --mode test", 9 | "lint": "vue-cli-service lint" 10 | }, 11 | "dependencies": { 12 | "@vue-materials/basic-container": "^1.0.0", 13 | "axios": "^0.18.0", 14 | "babel-polyfill": "^6.26.0", 15 | "better-scroll": "^1.12.6", 16 | "browserslist": "^4.8.0", 17 | "caniuse-lite": "^1.0.30001013", 18 | "echarts": "^4.2.0-rc.1", 19 | "element-ui": "^2.11.1", 20 | "flex.css": "^1.1.7", 21 | "js-cookie": "^2.2.0", 22 | "lodash": "^4.17.11", 23 | "lowdb": "^1.0.0", 24 | "net": "^1.0.2", 25 | "normalize.css": "^8.0.0", 26 | "nprogress": "^0.2.0", 27 | "socket.io": "^2.1.1", 28 | "socket.io-client": "^2.1.1", 29 | "stompjs": "^2.3.3", 30 | "ua-parser-js": "^0.7.18", 31 | "v-contextmenu": "^2.8.0", 32 | "vue": "^2.5.17", 33 | "vue-count-to": "^1.0.13", 34 | "vue-router": "^3.0.1", 35 | "vue-runtime-helpers": "^1.1.2", 36 | "vue-simple-uploader": "^0.5.4", 37 | "vuex": "^3.0.1" 38 | }, 39 | "devDependencies": { 40 | "@vue/cli-plugin-babel": "^3.0.3", 41 | "@vue/cli-plugin-eslint": "^3.0.3", 42 | "@vue/cli-service": "^3.0.3", 43 | "@vue/eslint-config-standard": "^3.0.3", 44 | "babel-eslint": "^10.0.3", 45 | "eslint": "^4.19.1", 46 | "eslint-friendly-formatter": "^4.0.1", 47 | "eslint-loader": "^2.1.2", 48 | "eslint-plugin-html": "^5.0.3", 49 | "eslint-plugin-vue": "^6.0.1", 50 | "node-sass": "^4.9.0", 51 | "sass-loader": "^7.0.1", 52 | "svg-sprite-loader": "^3.9.2", 53 | "vue-template-compiler": "^2.5.17" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /atp-web-open/src/pages/tools/tool-fareIncreaseService/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 52 | 53 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/views/tag.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | from flask import Blueprint, request 4 | from flask_restful import Resource 5 | from atp.api.redis_api import RedisManager 6 | from atp.api.mysql_manager import TestcaseTagManager 7 | from atp.views.wrappers import timer, login_check, developer_check 8 | from atp.utils.common import get_request_json, make_response 9 | 10 | redis = RedisManager() 11 | tag = Blueprint('tag_interface', __name__) 12 | 13 | 14 | class Tag(Resource): 15 | 16 | def __init__(self): 17 | self.data = get_request_json() 18 | self.ttm = TestcaseTagManager() 19 | self.username = redis.get_username(request.headers.get('X-Token')) 20 | if self.username: 21 | self.data["userName"] = self.username 22 | 23 | @timer 24 | def post(self, action): 25 | if action == 'list': 26 | return self.list() 27 | 28 | elif action == 'listForTask': 29 | return self.list_for_task() 30 | 31 | @login_check 32 | def list(self): 33 | tag_objs = self.ttm.query_testcase_tag() 34 | tag_map = {} 35 | for tag_obj in tag_objs: 36 | if tag_obj.tag_category not in tag_map: 37 | tag_map[tag_obj.tag_category] = [{"tagId": tag_obj.id, "tagName": tag_obj.tag_name}] 38 | else: 39 | tag_map[tag_obj.tag_category].append({"tagId": tag_obj.id, "tagName": tag_obj.tag_name}) 40 | 41 | return make_response({"code": "000", "tags": tag_map}) 42 | 43 | @login_check 44 | def list_for_task(self): 45 | tag_objs = self.ttm.query_testcase_tags(is_for_task=1) 46 | tag_list = [] 47 | for tag_obj in tag_objs: 48 | tag_list.append( 49 | { 50 | "tagId": tag_obj.id, 51 | "tagName": tag_obj.tag_name 52 | } 53 | ) 54 | return make_response({"code": "000", "tags": tag_list}) 55 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/theme.js: -------------------------------------------------------------------------------- 1 | // 设置文件 2 | import setting from '@/setting.js' 3 | 4 | export default { 5 | namespaced: true, 6 | state: { 7 | // 主题 8 | list: setting.theme.list, 9 | // 现在激活的主题 这应该是一个名字 不是对象 10 | activeName: setting.theme.list[0].name 11 | }, 12 | getters: { 13 | /** 14 | * @description 返回当前的主题信息 不是一个名字 而是当前激活主题的所有数据 15 | * @param {Object} state vuex state 16 | */ 17 | activeSetting(state) { 18 | return state.list.find(theme => theme.name === state.activeName) 19 | } 20 | }, 21 | mutations: { 22 | /** 23 | * @description 激活一个主题 24 | * @param {Object} state vuex state 25 | * @param {String} themeValue 需要激活的主题名称 26 | */ 27 | set(state, themeName) { 28 | // 检查这个主题在主题列表里是否存在 29 | state.activeName = state.list.find(e => e.name === themeName) ? themeName : state.list[0].name 30 | // 将 vuex 中的主题应用到 dom 31 | this.commit('d2admin/theme/dom') 32 | // 持久化 33 | this.dispatch('d2admin/db/set', { 34 | dbName: 'sys', 35 | path: 'theme.activeName', 36 | value: state.activeName, 37 | user: true 38 | }) 39 | }, 40 | /** 41 | * @description 从持久化数据加载主题设置 42 | * @param {Object} state vuex state 43 | */ 44 | async load(state) { 45 | // store 赋值 46 | this.commit('d2admin/theme/set', state, state.list[0].name) 47 | state.activeName = await this.dispatch('d2admin/db/get', { 48 | dbName: 'sys', 49 | path: 'theme.activeName', 50 | defaultValue: state.list[0].name, 51 | user: true 52 | }) 53 | // 更新到页面 54 | this.commit('d2admin/theme/dom') 55 | this.commit('d2admin/theme/set', state, state.list[0].name) 56 | }, 57 | /** 58 | * @description 将 vuex 中的主题应用到 dom 59 | * @param {Object} state vuex state 60 | */ 61 | dom(state) { 62 | document.body.className = `theme-${state.activeName}` 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /atp-web-open/src/pages/error-page-404/page.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 32 | 33 | 80 | -------------------------------------------------------------------------------- /atp-web-open/src/store/modules/d2admin/modules/menu.js: -------------------------------------------------------------------------------- 1 | // 设置文件 2 | import setting from '@/setting.js' 3 | 4 | export default { 5 | namespaced: true, 6 | state: { 7 | // 顶栏菜单 8 | header: [], 9 | // 侧栏菜单 10 | aside: [], 11 | // 侧边栏收缩 12 | asideCollapse: setting.menu.asideCollapse 13 | }, 14 | mutations: { 15 | /** 16 | * @description 设置顶栏菜单 17 | * @param {Object} state vuex state 18 | * @param {Array} menu menu setting 19 | */ 20 | headerSet(state, menu) { 21 | // store 赋值 22 | state.header = menu 23 | }, 24 | /** 25 | * @description 设置侧边栏菜单 26 | * @param {Object} state vuex state 27 | * @param {Array} menu menu setting 28 | */ 29 | asideSet(state, menu) { 30 | // store 赋值 31 | state.aside = menu 32 | }, 33 | /** 34 | * 设置侧边栏展开或者收缩 35 | * @param {Object} state vuex state 36 | * @param {Boolean} collapse is collapse 37 | */ 38 | asideCollapseSet(state, collapse) { 39 | // store 赋值 40 | state.asideCollapse = collapse 41 | // 持久化 42 | this.dispatch('d2admin/db/set', { 43 | dbName: 'sys', 44 | path: 'menu.asideCollapse', 45 | value: state.asideCollapse, 46 | user: true 47 | }) 48 | }, 49 | /** 50 | * 切换侧边栏展开和收缩 51 | * @param {Object} state vuex state 52 | */ 53 | asideCollapseToggle(state) { 54 | // store 赋值 55 | state.asideCollapse = !state.asideCollapse 56 | // 持久化 57 | this.dispatch('d2admin/db/set', { 58 | dbName: 'sys', 59 | path: 'menu.asideCollapse', 60 | value: state.asideCollapse, 61 | user: true 62 | }) 63 | }, 64 | /** 65 | * 从持久化数据读取侧边栏展开或者收缩 66 | * @param {Object} state vuex state 67 | */ 68 | async asideCollapseLoad(state) { 69 | // store 赋值 70 | state.asideCollapse = await this.dispatch('d2admin/db/get', { 71 | dbName: 'sys', 72 | path: 'menu.asideCollapse', 73 | defaultValue: setting.menu.asideCollapse, 74 | user: true 75 | }) 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/index.js: -------------------------------------------------------------------------------- 1 | // 组件库 2 | import autotestManage from './modules/autotest-manage' 3 | import sysManage from './modules/sys-manage' 4 | import tools from './modules/tools' 5 | import mock from './modules/mock' 6 | // import qadata from './modules/qadata' 7 | import home from './modules/home' 8 | import toolsDF from './modules/tools-df' 9 | import monitor from './modules/monitor' 10 | 11 | // 菜单 侧边栏 12 | let menuAside = null 13 | if (process.env.VUE_APP_CURRENTMODE === 'oq' || process.env.VUE_APP_CURRENTMODE === 'bf' || process.env.VUE_APP_CURRENTMODE === 'qj') { 14 | menuAside = [ 15 | home, 16 | // tools, 17 | autotestManage, 18 | mock, 19 | // qadata, 20 | sysManage 21 | ] 22 | } else if (process.env.VUE_APP_CURRENTMODE === 'df') { 23 | menuAside = [ 24 | home, 25 | // tools, 26 | toolsDF, 27 | autotestManage, 28 | mock, 29 | // qadata, 30 | sysManage 31 | ] 32 | } else { 33 | menuAside = [ 34 | home, 35 | tools, 36 | autotestManage, 37 | mock, 38 | monitor, 39 | // qadata, 40 | sysManage 41 | ] 42 | } 43 | // 菜单 顶栏 44 | let menuHeader = null 45 | if (process.env.VUE_APP_CURRENTMODE === 'oq' || process.env.VUE_APP_CURRENTMODE === 'bf' || process.env.VUE_APP_CURRENTMODE === 'qj') { 46 | menuHeader = [ 47 | { 48 | path: '/index', 49 | title: '首页', 50 | icon: 'home' 51 | }, 52 | // tools, 53 | autotestManage, 54 | mock, 55 | // qadata, 56 | sysManage 57 | ] 58 | } else if (process.env.VUE_APP_CURRENTMODE === 'df') { 59 | menuHeader = [ 60 | { 61 | path: '/index', 62 | title: '首页', 63 | icon: 'home' 64 | }, 65 | // tools, 66 | toolsDF, 67 | autotestManage, 68 | mock, 69 | // qadata, 70 | sysManage 71 | ] 72 | } else { 73 | menuHeader = [ 74 | { 75 | path: '/index', 76 | title: '首页', 77 | icon: 'home' 78 | }, 79 | tools, 80 | autotestManage, 81 | mock, 82 | monitor, 83 | // qadata, 84 | sysManage 85 | ] 86 | } 87 | 88 | export { menuAside, menuHeader } 89 | 90 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/tools.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '/tools', 3 | title: '工具管理', 4 | icon: 'wrench', 5 | children: (pre => [ 6 | { 7 | path: `${pre}tool`, 8 | title: '工具集', 9 | icon: 'key', 10 | children: [ 11 | { path: `${pre}tool-smsCodeQuery`, title: '查看验证码' }, 12 | { path: `${pre}tool-dataClean`, title: '数据清理' }, 13 | { path: `${pre}tool-creditWhiteList`, title: '征信白名单' }, 14 | { path: `${pre}tool-creditAuditQuery`, title: '征信审核结果查询' }, 15 | { path: `${pre}tool-loanDataCalculate`, title: '账务计算公式' }, 16 | { path: `${pre}tool-loanTransfer`, title: '一键放款' }, 17 | { path: `${pre}tool-updateLogisticsInfo`, title: '一键发货' }, 18 | { path: `${pre}tool-batchGenerateCardNo`, title: '一键生成银行卡号' }, 19 | { path: `${pre}tool-xmindToExcel`, title: 'xmind转excel' }, 20 | { path: `${pre}tool-uaaLogDecrypt`, title: '埋点日志解密' }, 21 | { path: `${pre}tool-loanDateToOverDue`, title: '构造账务逾期数据' }, 22 | { path: `${pre}tool-loanDateToOverDueForCapitalHub`, title: '构造账务逾期数据CH' }, 23 | { path: `${pre}tool-setMatchFund`, title: '设置资方匹配规则' }, 24 | { path: `${pre}tool-jsonTools`, title: 'json工具集' }, 25 | { path: `${pre}tool-sendMQ`, title: '发送MQ' }, 26 | { path: `${pre}tool-fareIncreaseService`, title: '现金贷加价策略配置' } 27 | ] 28 | }, 29 | { 30 | path: `${pre}info`, 31 | title: '信息查询', 32 | icon: 'search-plus', 33 | children: [ 34 | { path: `${pre}info-qrCodeApp`, title: '客户端二维码' }, 35 | { path: `${pre}info-hotLinksBaoSheng`, title: '宝生系统导航' } 36 | // { path: `${pre}info-hotLinksYaQiaoLi`, title: '雅俏丽系统导航' }, 37 | // { path: `${pre}info-hotLinksYouMi`, title: '又米系统导航' } 38 | ] 39 | } 40 | /* { 41 | path: `${pre}integration`, 42 | title: '持续集成', 43 | icon: 'recycle', 44 | children: [ 45 | { path: `${pre}integration-failReasonSet`, title: '登记失败原因' }, 46 | { path: `${pre}integration-greenChannelSet`, title: '发布UAT绿色通道' } 47 | ] 48 | }*/ 49 | ])('/tools/') 50 | } 51 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/shopping.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/send_email.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import os 4 | import smtplib 5 | import traceback 6 | from email.mime.multipart import MIMEMultipart 7 | from email.mime.base import MIMEBase 8 | from email.mime.text import MIMEText 9 | from email.utils import COMMASPACE, formatdate 10 | from email import encoders 11 | 12 | 13 | def example_intf_send_mail(): 14 | """ 15 | 样例代码 16 | :return: 17 | """ 18 | to = ['your.name@email.com'] 19 | subject = u'脚本运行提醒' 20 | text = u'脚本运行提醒' 21 | # files = ['send_mail.py'] 22 | # intf_send_mail(to,subject,text,files) 23 | intf_send_mail(to, subject, text) 24 | 25 | 26 | def intf_send_mail(to, subject, text, files=None): 27 | """ 28 | 发送邮件的接口,支持添加附件 29 | :param to: 邮件接收方 30 | :param subject: 邮件主题 31 | :param text: 邮件内容 32 | :param files: 附件路径 33 | :return: 34 | """ 35 | server = {'name': 'smtp.exmail.qq.com', 'user': 'user', 'passwd': 'password', 'port': 25} 36 | fro = 'spider.alarm@mi-me.com' 37 | send_mail(server, fro, to, subject, text, files=files) 38 | 39 | 40 | def send_mail(server, fro, to, subject, text, files=None): 41 | if not files: 42 | files = [] 43 | assert type(server) == dict 44 | assert type(to) == list 45 | assert type(files) == list 46 | 47 | msg = MIMEMultipart() 48 | msg['From'] = fro 49 | msg['Subject'] = subject 50 | msg['To'] = COMMASPACE.join(to) # COMMASPACE==', ' 51 | msg['Date'] = formatdate(localtime=True) 52 | msg.attach(MIMEText(text, 'plain', 'utf-8')) 53 | 54 | for f in files: 55 | part = MIMEBase('application', 'octet-stream') # 'octet-stream': binary data 56 | part.set_payload(open(f, 'rb').read()) 57 | encoders.encode_base64(part) 58 | part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f)) 59 | msg.attach(part) 60 | 61 | smtp = smtplib.SMTP(server['name'], server['port']) 62 | smtp.ehlo() 63 | smtp.starttls() 64 | smtp.ehlo() 65 | smtp.login(server['user'], server['passwd']) 66 | smtp.sendmail(fro, to, msg.as_string()) 67 | smtp.close() 68 | 69 | 70 | if __name__ == '__main__': 71 | pass 72 | 73 | 74 | -------------------------------------------------------------------------------- /atp-web-open/src/pages/tools/tool-loanTransferForDongFang/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 39 | 73 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/utils/background_log_thread.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import os 4 | import time 5 | 6 | from atp.config.default import get_config 7 | 8 | config = get_config() 9 | run_case_log_dir = config.RUN_CASE_LOG_DIR 10 | 11 | 12 | def background_log_thread(room): 13 | """""" 14 | count = 0 15 | 16 | g = create_generator('{dir}run_{report_id}.log'.format(dir=run_case_log_dir, report_id=room)) 17 | # g = create_generator('{dir}run_747.log'.format(dir=run_case_log_dir, report_id=room)) 18 | from atp import socketio 19 | for i in g: 20 | socketio.sleep(0.1) 21 | 22 | if isinstance(i, list): 23 | for p in i: 24 | print(p) 25 | p = p.replace(' ', '  ') 26 | socketio.emit('server_response', {'time': p, 'count': count}, namespace='/test', room=room) 27 | else: 28 | i = i.replace(' ', '  ') 29 | count += 1 30 | socketio.emit('server_response', {'time': i, 'count': count}, namespace='/test', room=room) 31 | if '【END】测试结束' in i: 32 | break 33 | 34 | 35 | def create_generator(file): 36 | # from atp import socketio 37 | s = 0 38 | while s < 10: 39 | is_exist = os.path.exists(file) 40 | if is_exist: 41 | break 42 | else: 43 | time.sleep(1) 44 | s += 1 45 | with open(file, 'r') as t: 46 | t.seek(0, 0) 47 | has_read = False 48 | _return_in_line = False 49 | 50 | while True: 51 | # 首次读取,直接返回已存在的所有行,类型是list 52 | if not has_read: 53 | exist_lines = t.readlines() 54 | has_read = True 55 | t.seek(0, 2) 56 | yield exist_lines 57 | 58 | # 按新增的行返回,类型是str 59 | elif _return_in_line: 60 | line = t.readline() 61 | if not line: 62 | time.sleep(0.1) 63 | continue 64 | yield line 65 | # 按新增的所有行返回,类型是list 66 | else: 67 | exist_lines = t.readlines() 68 | t.seek(0, 2) 69 | yield exist_lines 70 | 71 | 72 | if __name__ == '__main__': 73 | pass 74 | -------------------------------------------------------------------------------- /atp-web-open/src/pages/index/components/PieChart.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 83 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/dashboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/utils/get_content_from_log.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | ''' 4 | @time: 2019/12/24 12:38 5 | @desc: 6 | ''' 7 | import traceback 8 | import re 9 | import time 10 | from pathlib import Path, PurePosixPath 11 | from atp.api.ssh_client import SSHClient 12 | from atp.api.comm_log import logger 13 | 14 | 15 | class GetContenFromLog(object): 16 | """从日志文件中获取信息""" 17 | 18 | def __init__(self, system_name, server_info): 19 | self.system_path_name = system_name + '-cell01-node01' 20 | self.sys_log_path = Path('/usr/local/src/logs') / self.system_path_name / 'sys.log' 21 | self.sys_dubbo_provider_log_path = Path('/usr/local/src/logs') / self.system_path_name / 'sys-dubbo-provider.log' 22 | self.sys_dubbo_consumer_log_path = Path('/usr/local/src/logs') / self.system_path_name / 'sys-dubbo-consumer.log' 23 | self.sys_http_log_path = Path('/usr/local/src/logs') / self.system_path_name / 'sys-http.log' 24 | self.server_info = server_info 25 | self.start_time = int(time.time() - 600) * 1000 26 | self.end_time = int(time.time() + 600) * 1000 27 | 28 | def get_mq_log(self, topic, tag): 29 | """获取mq消息""" 30 | run_sh = 'grep -A 5 "cn.m*****mq" %s' % (PurePosixPath(self.sys_log_path)) 31 | # 连接服务器并执行shell命令 32 | with SSHClient(self.server_info) as sh: 33 | all_mq_log = sh.exec_cmd(run_sh) 34 | if not all_mq_log: 35 | return None 36 | try: 37 | # 解析返回内容 38 | for i in all_mq_log.split('\n--\n'): 39 | clean_data = [x for x in i.split('\n')] 40 | # 获取日志打印时间 41 | time_str = clean_data.pop(0) 42 | mat = re.search(r"(\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2})", time_str) 43 | log_time = int(time.mktime(time.strptime(mat.group(0), "%Y-%m-%d %H:%M:%S"))) * 1000 44 | # 只获取最近10分钟的日志 45 | if self.start_time < log_time < self.end_time: 46 | if topic in str(clean_data) and tag in str(clean_data): 47 | yield clean_data[4].split('=')[1].strip() 48 | except Exception as err: 49 | logger.error(traceback.format_exc()) 50 | raise err 51 | 52 | 53 | if __name__ == '__main__': 54 | pass 55 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/public-class.scss: -------------------------------------------------------------------------------- 1 | @import 'public'; 2 | 3 | // 补丁 base 4 | @import '~@/assets/style/fixed/base.scss'; 5 | // 补丁 element 6 | @import '~@/assets/style/fixed/element.scss'; 7 | 8 | // 动画 9 | @import '~@/assets/style/animate/vue-transition.scss'; 10 | 11 | // 在这里写公用的class 12 | // 注意 这个文件里只写class 13 | // mixin等内容请在 public.scss 里书写 14 | 15 | // 文字相关 16 | .#{$prefix}-text-center { 17 | text-align: center; 18 | } 19 | 20 | // 浮动相关 21 | .#{$prefix}-fl { 22 | float: left; 23 | } 24 | .#{$prefix}-fr { 25 | float: right; 26 | } 27 | .#{$prefix}-clearfix:before, 28 | .#{$prefix}-clearfix:after { 29 | display: table; 30 | content: ""; 31 | } 32 | .#{$prefix}-clearfix:after { 33 | clear: both 34 | } 35 | 36 | // 边距相关 37 | $sizes: (0, 5, 10, 15, 20); 38 | 39 | @for $index from 1 to 6 { 40 | .#{$prefix}-m-#{nth($sizes, $index)} { margin: #{nth($sizes, $index)}px !important; } 41 | .#{$prefix}-mt-#{nth($sizes, $index)} { margin-top: #{nth($sizes, $index)}px !important; } 42 | .#{$prefix}-mr-#{nth($sizes, $index)} { margin-right: #{nth($sizes, $index)}px !important; } 43 | .#{$prefix}-mb-#{nth($sizes, $index)} { margin-bottom: #{nth($sizes, $index)}px !important; } 44 | .#{$prefix}-ml-#{nth($sizes, $index)} { margin-left: #{nth($sizes, $index)}px !important; } 45 | 46 | .#{$prefix}-p-#{nth($sizes, $index)} { padding: #{nth($sizes, $index)}px !important; } 47 | .#{$prefix}-pt-#{nth($sizes, $index)} { padding-top: #{nth($sizes, $index)}px !important; } 48 | .#{$prefix}-pr-#{nth($sizes, $index)} { padding-right: #{nth($sizes, $index)}px !important; } 49 | .#{$prefix}-pb-#{nth($sizes, $index)} { padding-bottom: #{nth($sizes, $index)}px !important; } 50 | .#{$prefix}-pl-#{nth($sizes, $index)} { padding-left: #{nth($sizes, $index)}px !important; } 51 | } 52 | 53 | // 快速使用 54 | 55 | .#{$prefix}-m { margin: 20px !important; } 56 | .#{$prefix}-mt { margin-top: 20px !important; } 57 | .#{$prefix}-mr { margin-right: 20px !important; } 58 | .#{$prefix}-mb { margin-bottom: 20px !important; } 59 | .#{$prefix}-ml { margin-left: 20px !important; } 60 | 61 | .#{$prefix}-p { padding: 20px !important; } 62 | .#{$prefix}-pt { padding-top: 20px !important; } 63 | .#{$prefix}-pr { padding-right: 20px !important; } 64 | .#{$prefix}-pb { padding-bottom: 20px !important; } 65 | .#{$prefix}-pl { padding-left: 20px !important; } 66 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/resource-apiManage/company/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 获取公司列表 4 | */ 5 | 6 | export function fetchCompanyList(data) { 7 | return request({ 8 | url: '/atp/auto/apiCompany/list', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | 14 | /** 15 | * 新增公司 16 | */ 17 | 18 | export function addCompany(data) { 19 | return request({ 20 | url: '/atp/auto/apiCompany/add', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 删除公司 28 | */ 29 | 30 | export function deleteCompany(data) { 31 | return request({ 32 | url: '/atp/auto/apiCompany/delete', 33 | method: 'post', 34 | data 35 | }) 36 | } 37 | 38 | /** 39 | * 编辑公司 40 | */ 41 | 42 | export function editCompany(data) { 43 | return request({ 44 | url: '/atp/auto/apiCompany/edit', 45 | method: 'post', 46 | data 47 | }) 48 | } 49 | 50 | /** 51 | * 公司id获取工程树结构 52 | */ 53 | 54 | export function subtree(data) { 55 | return request({ 56 | url: '/atp/auto/apiCompany/subtree', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * 公司id获取项目树结构 64 | */ 65 | 66 | export function subtreeProject(data) { 67 | return request({ 68 | url: '/atp/auto/apiCompany/projectSubtree', 69 | method: 'post', 70 | data 71 | }) 72 | } 73 | 74 | /** 75 | * 公司id获取全链路用例树 76 | */ 77 | 78 | export function subtreeProductLine(data) { 79 | return request({ 80 | url: '/atp/auto/apiCompany/productLineSubtree', 81 | method: 'post', 82 | data 83 | }) 84 | } 85 | 86 | /** 87 | * 根据公司id查询,查询全链路用例可选择系统/接口/用例 88 | */ 89 | 90 | export function subtreeIntfCase(data) { 91 | return request({ 92 | url: '/atp/auto/apiCompany/intfCaseSubtree', 93 | method: 'post', 94 | data 95 | }) 96 | } 97 | 98 | /** 99 | * 获取用例查询条件 100 | */ 101 | 102 | export function getFilterConditions(data) { 103 | return request({ 104 | url: '/atp/auto/apiCompany/getFilterConditions', 105 | method: 'post', 106 | data 107 | }) 108 | } 109 | 110 | /** 111 | * 根据关键字查询用例 112 | */ 113 | 114 | export function subtreeFilter(data) { 115 | return request({ 116 | url: '/atp/auto/apiCompany/subtreeFilter', 117 | method: 'post', 118 | data 119 | }) 120 | } 121 | -------------------------------------------------------------------------------- /atp-web-open/src/menu/modules/autotest-manage.js: -------------------------------------------------------------------------------- 1 | export default { 2 | path: '/autotest/manage', 3 | title: '自动化管理', 4 | icon: 'android', 5 | children: (pre => [ 6 | { 7 | path: `${pre}resource`, 8 | title: '资源配置', 9 | icon: 'cube', 10 | children: [ 11 | { path: `${pre}resource-interfaceManage`, title: '接口管理' }, 12 | { path: `${pre}resource-envManage`, title: '环境配置' }, 13 | { path: `${pre}resource-publicVariable`, title: '公共变量' } 14 | ] 15 | }, 16 | { 17 | path: `${pre}intf-testcase`, 18 | title: '自动化用例', 19 | icon: 'car', 20 | children: [ 21 | { path: `${pre}interface-testCaseConfig`, title: '接口用例配置' }, 22 | { path: `${pre}fullLine-testCaseConfig`, title: '全链路用例配置' } 23 | // {path: `${pre}interface-test`, title: '测试编辑页面'}, 24 | ] 25 | }, 26 | { 27 | path: `${pre}func-testcase`, 28 | title: '业务用例', 29 | icon: 'bicycle', 30 | children: [ 31 | { path: `${pre}base-testCaseConfig`, title: '业务用例管理' } 32 | ] 33 | }, 34 | /* { 35 | path: `${pre}uitestcase`, 36 | title: 'UI自动化管理', 37 | icon: 'wrench', 38 | children: [ 39 | { path: `${pre}uiautomation-testCaseConfig`, title: 'UI自动化用例配置' }, 40 | { path: `${pre}uiautomation-pageObjectConfig`, title: '页面元素对象配置' }, 41 | ] 42 | },*/ 43 | { 44 | path: `${pre}testTask`, 45 | title: '自动化测试', 46 | icon: 'retweet', 47 | children: [ 48 | { path: `${pre}testTask-smokingTest`, title: 'CI冒烟测试' }, 49 | { path: `${pre}testTask-regressionTest`, title: 'CI回归测试' }, 50 | { path: `${pre}testTask-manualConfig`, title: '人工配置' } 51 | ] 52 | }, 53 | /* { 54 | path: `${pre}report`, 55 | title: '报告管理', 56 | icon: 'file-word-o', 57 | children: [ 58 | // {path: `${pre}report-cronJob`, title: '定时任务测试报告'}, 59 | {path: `${pre}report-view`, title: '测试报告展示'} 60 | ] 61 | },*/ 62 | { 63 | path: `${pre}dataAnalysis`, 64 | title: '数据分析', 65 | icon: 'line-chart', 66 | children: [ 67 | // {path: `${pre}dataAnalysis-coverageRate`, title: '自动化覆盖率'}, 68 | { path: `${pre}dataAnalysis-regressionResult`, title: '回归测试结果' }, 69 | { path: `${pre}dataAnalysis-reuseRate`, title: '自动化复用率' } 70 | ] 71 | } 72 | ])('/autotest/manage/') 73 | } 74 | -------------------------------------------------------------------------------- /atp-web-open/src/icons/svg/form.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testTask-manualConfig/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 新增task 4 | */ 5 | 6 | export function addTask(data) { 7 | return request({ 8 | url: '/atp/auto/apiTask/add', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | /** 14 | * 编辑task 15 | */ 16 | 17 | export function editTask(data) { 18 | return request({ 19 | url: '/atp/auto/apiTask/edit', 20 | method: 'post', 21 | data 22 | }) 23 | } 24 | /** 25 | * 删除task 26 | */ 27 | 28 | export function deleteTask(data) { 29 | return request({ 30 | url: '/atp/auto/apiTask/delete', 31 | method: 'post', 32 | data 33 | }) 34 | } 35 | /** 36 | * 运行task 37 | */ 38 | 39 | export function runTask(data) { 40 | return request({ 41 | url: '/atp/auto/apiTask/run', 42 | method: 'post', 43 | data 44 | }) 45 | } 46 | 47 | /** 48 | * task详情 49 | */ 50 | 51 | export function detailTask(data) { 52 | return request({ 53 | url: '/atp/auto/apiTask/detail', 54 | method: 'post', 55 | data 56 | }) 57 | } 58 | 59 | /** 60 | * 查询任务列表 61 | */ 62 | 63 | export function listTask(data) { 64 | return request({ 65 | url: '/atp/auto/apiTask/list', 66 | method: 'post', 67 | data 68 | }) 69 | } 70 | 71 | /** 72 | * 查询任务进度 73 | */ 74 | 75 | export function getProgress(data) { 76 | return request({ 77 | url: '/atp/auto/apiTask/getProgress', 78 | method: 'post', 79 | data 80 | }) 81 | } 82 | 83 | /** 84 | * 获取任务运行历史列表 85 | */ 86 | 87 | export function runHistory(data) { 88 | return request({ 89 | url: '/atp/auto/apiTask/runHistory', 90 | method: 'post', 91 | data 92 | }) 93 | } 94 | 95 | /** 96 | * 获取任务未覆盖的接口信息 97 | */ 98 | 99 | export function getUncoveredInfo(data) { 100 | return request({ 101 | url: '/atp/auto/apiTask/getUncoveredInfo', 102 | method: 'post', 103 | data 104 | }) 105 | } 106 | 107 | /** 108 | * 标签列表 109 | */ 110 | 111 | export function listForTask(data) { 112 | return request({ 113 | url: '/atp/auto/tag/listForTask', 114 | method: 'post', 115 | data 116 | }) 117 | } 118 | 119 | /** 120 | * 重新触发收集测试结果 121 | */ 122 | 123 | export function reCollectTaskResult(data) { 124 | return request({ 125 | url: '/atp/auto/apiTask/reCollectTaskResult', 126 | method: 'post', 127 | data 128 | }) 129 | } 130 | -------------------------------------------------------------------------------- /atp-web-open/src/assets/style/theme/atp/setting.scss: -------------------------------------------------------------------------------- 1 | // 主题名称 2 | $theme-name: 'atp'; 3 | // 主题背景颜色 4 | $theme-bg-color: #ebf1f6; 5 | // 主题背景图片遮罩 6 | $theme-bg-mask: rgba(#000, 0); 7 | 8 | // container组件 9 | $theme-container-background-color: rgba(#FFF, 1); 10 | $theme-container-header-footer-background-color: #FFF; 11 | $theme-container-border-inner: 1px solid #cfd7e5; 12 | $theme-container-border-outer: 1px solid #cfd7e5; 13 | 14 | $theme-multiple-page-control-color: $color-text-normal; 15 | $theme-multiple-page-control-color-active: #2f74ff; 16 | $theme-multiple-page-control-nav-prev-color: #cfd7e5; 17 | $theme-multiple-page-control-nav-next-color: #cfd7e5; 18 | $theme-multiple-page-control-border-color: #cfd7e5; 19 | $theme-multiple-page-control-border-color-active: #FFF; 20 | $theme-multiple-page-control-background-color: rgba(#000, .03); 21 | $theme-multiple-page-control-background-color-active: #FFF; 22 | 23 | // 顶栏和侧边栏中展开的菜单 hover 状态下 24 | $theme-menu-item-color-hover: #293849; 25 | $theme-menu-item-background-color-hover: #ecf5ff; 26 | 27 | // 顶栏上的文字颜色 28 | $theme-header-item-color: #FFF; 29 | $theme-header-item-background-color: transparent; 30 | // 顶栏上的项目在 hover 时 31 | $theme-header-item-color-hover: #2f74ff; 32 | $theme-header-item-background-color-hover: rgba(#FFF, .5); 33 | // 顶栏上的项目在 focus 时 34 | $theme-header-item-color-focus: #2f74ff; 35 | $theme-header-item-background-color-focus: rgba(#FFF, .5); 36 | // 顶栏上的项目在 active 时 37 | $theme-header-item-color-active: #2f74ff; 38 | $theme-header-item-background-color-active: rgba(#FFF, .5); 39 | 40 | // 侧边栏上的文字颜色 41 | $theme-aside-item-color: $color-text-normal; 42 | $theme-aside-item-background-color: transparent; 43 | // 侧边栏上的项目在 hover 时 44 | $theme-aside-item-color-hover: #2f74ff; 45 | $theme-aside-item-background-color-hover: rgba(#FFF, .5); 46 | // 侧边栏上的项目在 focus 时 47 | $theme-aside-item-color-focus: #2f74ff; 48 | $theme-aside-item-background-color-focus: rgba(#FFF, .5); 49 | // 侧边栏上的项目在 active 时 50 | $theme-aside-item-color-active: #2f74ff; 51 | $theme-aside-item-background-color-active: rgba(#FFF, .5); 52 | 53 | // 侧边栏菜单为空的时候显示的元素 54 | $theme-aside-menu-empty-icon-color: $color-text-normal; 55 | $theme-aside-menu-empty-text-color: $color-text-normal; 56 | $theme-aside-menu-empty-background-color: rgba(#000, .03); 57 | $theme-aside-menu-empty-icon-color-hover: $color-text-main; 58 | $theme-aside-menu-empty-text-color-hover: $color-text-main; 59 | $theme-aside-menu-empty-background-color-hover: rgba(#000, .05); 60 | -------------------------------------------------------------------------------- /atp-web-open/src/api/autotest/manage/testTask-regressionTest/index.js: -------------------------------------------------------------------------------- 1 | import request from '@/plugin/axios' 2 | /** 3 | * 新增task 4 | */ 5 | 6 | export function addTask(data) { 7 | return request({ 8 | url: '/atp/auto/apiTask/add', 9 | method: 'post', 10 | data 11 | }) 12 | } 13 | /** 14 | * 编辑task 15 | */ 16 | 17 | export function editTask(data) { 18 | return request({ 19 | url: '/atp/auto/apiTask/edit', 20 | method: 'post', 21 | data 22 | }) 23 | } 24 | /** 25 | * 删除task 26 | */ 27 | 28 | export function deleteTask(data) { 29 | return request({ 30 | url: '/atp/auto/apiTask/delete', 31 | method: 'post', 32 | data 33 | }) 34 | } 35 | /** 36 | * 运行task 37 | */ 38 | 39 | export function runTask(data) { 40 | return request({ 41 | url: '/atp/auto/apiTask/run', 42 | method: 'post', 43 | data 44 | }) 45 | } 46 | 47 | /** 48 | * task详情 49 | */ 50 | 51 | export function detailTask(data) { 52 | return request({ 53 | url: '/atp/auto/apiTask/detail', 54 | method: 'post', 55 | data 56 | }) 57 | } 58 | 59 | /** 60 | * 查询任务列表 61 | */ 62 | 63 | export function listRegressionTask(data) { 64 | return request({ 65 | url: '/atp/auto/apiTask/listRegressionTask', 66 | method: 'post', 67 | data 68 | }) 69 | } 70 | 71 | /** 72 | * 查询任务进度 73 | */ 74 | 75 | export function getProgress(data) { 76 | return request({ 77 | url: '/atp/auto/apiTask/getProgress', 78 | method: 'post', 79 | data 80 | }) 81 | } 82 | 83 | /** 84 | * 获取任务运行历史列表 85 | */ 86 | 87 | export function runHistory(data) { 88 | return request({ 89 | url: '/atp/auto/apiTask/runHistory', 90 | method: 'post', 91 | data 92 | }) 93 | } 94 | 95 | /** 96 | * 获取任务未覆盖的接口信息 97 | */ 98 | 99 | export function getUncoveredInfo(data) { 100 | return request({ 101 | url: '/atp/auto/apiTask/getUncoveredInfo', 102 | method: 'post', 103 | data 104 | }) 105 | } 106 | 107 | /** 108 | * 标签列表 109 | */ 110 | 111 | export function listForTask(data) { 112 | return request({ 113 | url: '/atp/auto/tag/listForTask', 114 | method: 'post', 115 | data 116 | }) 117 | } 118 | 119 | /** 120 | * 重新触发收集测试结果 121 | */ 122 | 123 | export function reCollectTaskResult(data) { 124 | return request({ 125 | url: '/atp/auto/apiTask/reCollectTaskResult', 126 | method: 'post', 127 | data 128 | }) 129 | } 130 | -------------------------------------------------------------------------------- /atp-auto-core-open/atp/api/safe_file_handler.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import codecs 4 | import os 5 | import time 6 | 7 | from logging import FileHandler 8 | 9 | 10 | class SafeFileHandler(FileHandler): 11 | def __init__(self, filename, mode='a', encoding=None, delay=0): 12 | """ 13 | Use the specified filename for streamed logging 14 | """ 15 | if codecs is None: 16 | encoding = None 17 | FileHandler.__init__(self, filename, mode, encoding, delay) 18 | self.mode = mode 19 | self.encoding = encoding 20 | self.suffix = "%Y-%m-%d" 21 | self.suffix_time = "" 22 | 23 | def emit(self, record): 24 | """ 25 | Emit a record. 26 | 27 | Always check time 28 | """ 29 | try: 30 | if self.check_baseFilename(record): 31 | self.build_baseFilename() 32 | FileHandler.emit(self, record) 33 | except (KeyboardInterrupt, SystemExit): 34 | raise 35 | except: 36 | self.handleError(record) 37 | 38 | def check_baseFilename(self, record): 39 | """ 40 | Determine if builder should occur. 41 | 42 | record is not used, as we are just comparing times, 43 | but it is needed so the method signatures are the same 44 | """ 45 | timeTuple = time.localtime() 46 | 47 | if self.suffix_time != time.strftime(self.suffix, timeTuple) or not os.path.exists(self.baseFilename+'.'+self.suffix_time): 48 | return 1 49 | else: 50 | return 0 51 | 52 | def build_baseFilename(self): 53 | """ 54 | do builder; in this case, 55 | old time stamp is removed from filename and 56 | a new time stamp is append to the filename 57 | """ 58 | if self.stream: 59 | self.stream.close() 60 | self.stream = None 61 | 62 | # remove old suffix 63 | if self.suffix_time != "": 64 | index = self.baseFilename.find("."+self.suffix_time) 65 | if index == -1: 66 | index = self.baseFilename.rfind(".") 67 | self.baseFilename = self.baseFilename[:index] 68 | 69 | # add new suffix 70 | currentTimeTuple = time.localtime() 71 | self.suffix_time = time.strftime(self.suffix, currentTimeTuple) 72 | self.baseFilename = self.baseFilename + "." + self.suffix_time 73 | 74 | self.mode = 'a' 75 | if not self.delay: 76 | self.stream = self._open() 77 | --------------------------------------------------------------------------------