├── static
├── .gitkeep
└── favicon.ico
├── config
├── prod.env.js
├── dev.env.js
└── index.js
├── src
├── store
│ ├── state.js
│ ├── index.js
│ └── mutations.js
├── assets
│ ├── images
│ │ ├── bottom-left.png
│ │ └── bottom-right.png
│ └── styles
│ │ ├── icon-font
│ │ ├── iconfont.eot
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ │ ├── reports.css
│ │ ├── tree.css
│ │ ├── swagger.css
│ │ ├── home.css
│ │ └── iconfont.css
├── App.vue
├── pages
│ ├── home
│ │ ├── Home.vue
│ │ └── components
│ │ │ ├── Header.vue
│ │ │ └── Side.vue
│ ├── project
│ │ ├── ProjectDetail.vue
│ │ └── ProjectList.vue
│ ├── httprunner
│ │ ├── components
│ │ │ ├── Hooks.vue
│ │ │ ├── Extract.vue
│ │ │ ├── Parameters.vue
│ │ │ ├── Headers.vue
│ │ │ ├── Variables.vue
│ │ │ └── Validate.vue
│ │ └── DebugTalk.vue
│ ├── auth
│ │ ├── components
│ │ │ ├── Login.vue
│ │ │ └── Register.vue
│ │ ├── Login.vue
│ │ └── Register.vue
│ ├── config
│ │ ├── RecordConfig.vue
│ │ └── components
│ │ │ ├── ConfigBody.vue
│ │ │ └── ConfigList.vue
│ ├── fastrunner
│ │ ├── config
│ │ │ ├── RecordConfig.vue
│ │ │ └── components
│ │ │ │ ├── ConfigBody.vue
│ │ │ │ └── ConfigList.vue
│ │ └── case
│ │ │ └── components
│ │ │ └── TestBody.vue
│ ├── task
│ │ └── Tasks.vue
│ └── reports
│ │ └── DebugReport.vue
├── main.js
├── router
│ └── index.js
└── restful
│ └── api.js
├── .editorconfig
├── .gitignore
├── .babelrc
├── .postcssrc.js
├── Dockerfile
├── default.conf
├── index.html
├── README.md
├── LICENSE
└── package.json
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/httprunner/FasterWeb/HEAD/static/favicon.ico
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"',
4 | }
5 |
--------------------------------------------------------------------------------
/src/store/state.js:
--------------------------------------------------------------------------------
1 | export default {
2 | routerName: null,
3 | token:null,
4 | user: null
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/src/assets/images/bottom-left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/httprunner/FasterWeb/HEAD/src/assets/images/bottom-left.png
--------------------------------------------------------------------------------
/src/assets/images/bottom-right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/httprunner/FasterWeb/HEAD/src/assets/images/bottom-right.png
--------------------------------------------------------------------------------
/src/assets/styles/icon-font/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/httprunner/FasterWeb/HEAD/src/assets/styles/icon-font/iconfont.eot
--------------------------------------------------------------------------------
/src/assets/styles/icon-font/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/httprunner/FasterWeb/HEAD/src/assets/styles/icon-font/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/styles/icon-font/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/httprunner/FasterWeb/HEAD/src/assets/styles/icon-font/iconfont.woff
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"',
7 | })
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import state from './state'
4 | import mutations from './mutations'
5 |
6 | Vue.use(Vuex)
7 |
8 | export default new Vuex.Store({
9 | state,
10 | mutations
11 | })
12 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-vue-jsx", "transform-runtime"]
12 | }
13 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-import": {},
6 | "postcss-url": {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | "autoprefixer": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | isLogin(state, value) {
4 | state.token = value;
5 | },
6 |
7 | setUser(state, value) {
8 | state.user = value;
9 | },
10 | setRouterName(state, value) {
11 | state.routerName = value
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM hub.c.163.com/library/nginx
2 |
3 | MAINTAINER yinquanwang
4 |
5 | RUN rm /etc/nginx/conf.d/default.conf
6 |
7 | RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
8 |
9 | ADD default.conf /etc/nginx/conf.d/
10 |
11 | COPY dist/ /usr/share/nginx/html/
12 |
--------------------------------------------------------------------------------
/default.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 8080;
3 | server_name localhost; # 修改为docker服务宿主机的ip
4 |
5 | location / {
6 | root /usr/share/nginx/html;
7 | index index.html index.htm;
8 | try_files $uri $uri/ /index.html =404;
9 | }
10 |
11 | error_page 500 502 503 504 /50x.html;
12 | location = /50x.html {
13 | root html;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | FastRunner
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FasterWeb
2 |
3 | 
4 | > FasterWeb that depends FasterRunner
5 |
6 | ## 本地开发环境部署
7 |
8 | ``` bash
9 | # install dependencies
10 | npm install
11 |
12 | # serve with hot reload at localhost:8080
13 | npm run dev
14 |
15 | ```
16 |
17 | 测试
18 | -----------
19 |
20 | 1. open url(recommend chrome): http://localhost:8080/fastrunner/register
21 |
22 | ## Docker 部署 nginx模式
23 | --------------
24 | 1. 修改default.conf配置文件 server_name的ip(宿主机IP), 端口默认8080
25 | 2. 修改/src/restful/api.js baseUrl地址, 即为fastrunner容器运行的宿主机地址
26 | 3. 执行npm install, npm run build # 生成生产环境包
27 | 3. docker build -t fasterweb:latest . # 构建docker镜像
28 | 4. docker run -d --name fasterweb --net=host --restart always fasterweb:latest # 后台运行docker容器
29 | 5. open url: http://宿主机ip:8080/fastrunner/register
30 |
--------------------------------------------------------------------------------
/src/pages/home/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
34 |
35 |
41 |
--------------------------------------------------------------------------------
/src/assets/styles/reports.css:
--------------------------------------------------------------------------------
1 | .success {
2 | font-weight: bold;
3 | font-size: medium;
4 | color: #67c23a;
5 | }
6 |
7 | .error {
8 | font-weight: bold;
9 | font-size: medium;
10 | color: red;
11 | }
12 |
13 | .failure {
14 | font-weight: bold;
15 | font-size: medium;
16 | color: salmon;
17 | }
18 |
19 | .skipped {
20 | font-weight: bold;
21 | font-size: medium;
22 | color: #909399;
23 | }
24 |
25 | .POST {
26 | color: #49cc90;
27 | }
28 |
29 |
30 | .PUT {
31 | color: #fca130;
32 | }
33 |
34 | .GET {
35 | color: #61affe;
36 | }
37 |
38 |
39 | .DELETE {
40 | color: #f93e3e;
41 | }
42 |
43 |
44 | .PATCH {
45 | color: #50e3c2;
46 | }
47 |
48 | .HEAD {
49 | color: #e6a23c;
50 | }
51 |
52 | .OPTIONS {
53 | color: #409eff;
54 | }
55 |
56 |
57 | .code-block {
58 |
59 | border: 1px solid #ebedef;
60 | border-radius: 4px;
61 | color: #222 !important;
62 | font-family: Consolas,monospace;
63 | font-size: 13px;
64 | margin: 0;
65 | padding: 7px 10px;
66 | overflow: auto;
67 | }
68 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 yinquanwang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/assets/styles/tree.css:
--------------------------------------------------------------------------------
1 | ul li {
2 | list-style: none;
3 | }
4 |
5 | .operation-li {
6 | line-height: 60px;
7 | color: #555;
8 | font-size: 12px;
9 | width: 240px;
10 | margin-top: 1px;
11 | }
12 |
13 | .api-tree {
14 | padding: 0;
15 | margin: 0;
16 | }
17 |
18 | .nav-api-header {
19 | height: 48px;
20 | border-bottom: 1px solid #ddd;
21 | background-color: #F7F7F7;
22 |
23 | }
24 |
25 | .nav-api-side {
26 | overflow: auto;
27 | border: 1px solid #ddd;
28 | width: 280px;
29 | margin-left: 10px;
30 | border-radius: 4px;
31 | position: fixed;
32 | top: 110px;
33 | bottom: 0;
34 |
35 | }
36 |
37 | .custom-tree-node {
38 | flex: 1;
39 | display: flex;
40 | align-items: center;
41 | justify-content: space-between;
42 | font-size: 14px;
43 | padding-right: 8px;
44 | }
45 |
46 |
47 | .tree {
48 | overflow-y: auto;
49 | overflow-x: auto;
50 | width: 280px;
51 | height: 500px;
52 | }
53 |
54 | .el-tree {
55 | min-width: 100%;
56 | display: inline-block !important;
57 | }
58 |
59 | .el-tree-node__expand-icon {
60 | padding: 4px !important;
61 | }
62 |
63 | .el-tree-node__content {
64 | height: 50px;
65 | }
66 |
67 | .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
68 | background-color: rgba(64, 158, 255, .1);
69 | color: #409EFF;
70 | }
71 |
--------------------------------------------------------------------------------
/src/pages/home/components/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
19 |
20 |
21 |
22 |
36 |
37 |
75 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api-web",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "尹全旺 <1263374981@qq.com>",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "build": "node build/build.js"
11 | },
12 | "dependencies": {
13 | "axios": "^0.18.0",
14 | "element-ui": "^2.4.6",
15 | "vue": "^2.5.2",
16 | "vue-monaco-editor": "0.0.19",
17 | "vue-router": "^3.0.1",
18 | "vuedraggable": "^2.16.0",
19 | "vuex": "^3.0.1"
20 | },
21 | "devDependencies": {
22 | "autoprefixer": "^7.1.2",
23 | "babel-core": "^6.22.1",
24 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
25 | "babel-loader": "^7.1.1",
26 | "babel-plugin-syntax-jsx": "^6.18.0",
27 | "babel-plugin-transform-runtime": "^6.22.0",
28 | "babel-plugin-transform-vue-jsx": "^3.5.0",
29 | "babel-preset-env": "^1.3.2",
30 | "babel-preset-stage-2": "^6.22.0",
31 | "chalk": "^2.0.1",
32 | "copy-webpack-plugin": "^4.0.1",
33 | "css-loader": "^0.28.0",
34 | "extract-text-webpack-plugin": "^3.0.0",
35 | "file-loader": "^1.1.4",
36 | "friendly-errors-webpack-plugin": "^1.6.1",
37 | "html-webpack-plugin": "^2.30.1",
38 | "node-notifier": "^5.1.2",
39 | "optimize-css-assets-webpack-plugin": "^3.2.0",
40 | "ora": "^1.2.0",
41 | "portfinder": "^1.0.13",
42 | "postcss-import": "^11.0.0",
43 | "postcss-loader": "^2.0.8",
44 | "postcss-url": "^7.2.1",
45 | "rimraf": "^2.6.0",
46 | "semver": "^5.3.0",
47 | "shelljs": "^0.7.6",
48 | "uglifyjs-webpack-plugin": "^1.1.1",
49 | "url-loader": "^0.5.8",
50 | "vue-easytable": "^1.7.1",
51 | "vue-loader": "^13.3.0",
52 | "vue-style-loader": "^3.0.1",
53 | "vue-template-compiler": "^2.5.2",
54 | "vue2-ace-editor": "0.0.11",
55 | "webpack": "^3.6.0",
56 | "webpack-bundle-analyzer": "^2.9.0",
57 | "webpack-dev-server": "^2.9.1",
58 | "webpack-merge": "^4.1.0"
59 | },
60 | "engines": {
61 | "node": ">= 6.0.0",
62 | "npm": ">= 3.0.0"
63 | },
64 | "browserslist": [
65 | "> 1%",
66 | "last 2 versions",
67 | "not ie <= 8"
68 | ]
69 | }
70 |
--------------------------------------------------------------------------------
/src/pages/home/components/Side.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 | 首 页
13 |
14 |
15 |
20 |
21 |
22 |
23 | {{item.name}}
24 |
25 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
62 |
63 |
75 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.3.1
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {
14 | /* '/httprunner': {
15 | target: 'http://localhost:8000',//设置你调用的接口域名和端口号 别忘了加http
16 | changeOrigin: true,
17 | pathRewrite: {
18 | '^/httprunner': ''
19 | }
20 | }*/
21 | },
22 |
23 | // Various Dev Server settings
24 | host: 'localhost', // can be overwritten by process.variables.HOST
25 | port: 8080, // can be overwritten by process.variables.PORT, if port is in use, a free one will be determined
26 | autoOpenBrowser: false,
27 | errorOverlay: true,
28 | notifyOnErrors: true,
29 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
30 |
31 |
32 | /**
33 | * Source Maps
34 | */
35 |
36 | // https://webpack.js.org/configuration/devtool/#development
37 | devtool: 'cheap-module-eval-source-map',
38 |
39 | // If you have problems debugging vue-files in devtools,
40 | // set this to false - it *may* help
41 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
42 | cacheBusting: true,
43 |
44 | cssSourceMap: true
45 | },
46 |
47 | build: {
48 | // Template for index.html
49 | index: path.resolve(__dirname, '../dist/index.html'),
50 |
51 | // Paths
52 | assetsRoot: path.resolve(__dirname, '../dist'),
53 | assetsSubDirectory: 'static',
54 | assetsPublicPath: '/',
55 |
56 | /**
57 | * Source Maps
58 | */
59 |
60 | productionSourceMap: true,
61 | // https://webpack.js.org/configuration/devtool/#production
62 | devtool: '#source-map',
63 |
64 | // Gzip off by default as many popular static hosts such as
65 | // Surge or Netlify already gzip all static assets for you.
66 | // Before setting to `true`, make sure to:
67 | // npm install --save-dev compression-webpack-plugin
68 | productionGzip: false,
69 | productionGzipExtensions: ['js', 'css'],
70 |
71 | // Run the build command with an extra argument to
72 | // View the bundle analyzer report after build finishes:
73 | // `npm run build --report`
74 | // Set to `true` or `false` to always turn it on or off
75 | bundleAnalyzerReport: process.env.npm_config_report
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/assets/styles/swagger.css:
--------------------------------------------------------------------------------
1 | .block_post {
2 | border: 1px solid #49cc90;
3 | background-color: rgba(73, 204, 144, .1)
4 | }
5 |
6 | .block_method_post {
7 | background-color: #49cc90;
8 | }
9 |
10 | .block_put {
11 | border: 1px solid #fca130;
12 | background-color: rgba(252, 161, 48, .1)
13 | }
14 |
15 | .block_method_put {
16 | background-color: #fca130;
17 | }
18 |
19 | .block_get {
20 | border: 1px solid #61affe;
21 | background-color: rgba(97, 175, 254, .1)
22 | }
23 |
24 | .block_method_get {
25 | background-color: #61affe;
26 | }
27 |
28 | .block_delete {
29 | border: 1px solid #f93e3e;
30 | background-color: rgba(249, 62, 62, .1)
31 | }
32 |
33 | .block_method_delete {
34 | background-color: #f93e3e;
35 | }
36 |
37 | .block_patch {
38 | border: 1px solid #50e3c2;
39 | background-color: rgba(80, 227, 194, .1)
40 | }
41 |
42 | .block_method_patch {
43 | background-color: #50e3c2;
44 | }
45 |
46 | .block_head {
47 | border: 1px solid #e6a23c;
48 | background-color: rgba(230, 162, 60, .1)
49 | }
50 |
51 | .block_method_head {
52 | background-color: #e6a23c;
53 | }
54 |
55 | .block_options {
56 | border: 1px solid #409eff;
57 | background-color: rgba(64, 158, 255, .1)
58 | }
59 |
60 | .block_method_options {
61 | background-color: #409eff;
62 | }
63 |
64 | .block {
65 | position: relative;
66 | border-radius: 4px;
67 | height: 43.6px;
68 | padding: 5px;
69 | display: flex;
70 | align-items: center;
71 | }
72 |
73 | .block_url {
74 | word-break: normal;
75 | width: auto;
76 | display: block;
77 | white-space: pre-wrap;
78 | word-wrap: break-word;
79 | overflow: hidden;
80 | -webkit-box-flex: 1;
81 | -ms-flex: 1;
82 | font-family: Open Sans, sans-serif;
83 | color: #3b4151;
84 | }
85 |
86 | .block_name {
87 | padding-left: 5px;
88 | word-break: normal;
89 | width: auto;
90 | display: block;
91 | white-space: pre-wrap;
92 | word-wrap: break-word;
93 | overflow: hidden;
94 | -webkit-box-flex: 1;
95 | -ms-flex: 1;
96 | font-family: Open Sans, sans-serif;
97 | color: #3b4151;
98 | }
99 |
100 | .block_method_color {
101 | cursor: pointer;
102 | color: #fff;
103 | }
104 |
105 | .block-method {
106 | font-size: 14px;
107 | font-weight: 600;
108 | min-width: 80px;
109 | padding: 6px 15px;
110 | text-align: center;
111 | border-radius: 3px;
112 | text-shadow: 0 1px 0 rgba(0, 0, 0, .1);
113 | font-family: Titillium Web, sans-serif;
114 | }
115 |
116 | .block-summary-description {
117 | word-break: normal;
118 | width: auto;
119 | display: block;
120 | white-space: pre-wrap;
121 | word-wrap: break-word;
122 | overflow: hidden;
123 | -webkit-box-flex: 1;
124 | -ms-flex: 1;
125 | font-family: Open Sans, sans-serif;
126 | color: #3b4151;
127 | }
128 |
129 | h4 {
130 | display: block;
131 | -webkit-margin-before: 1.33em;
132 | -webkit-margin-after: 1.33em;
133 | -webkit-margin-start: 0px;
134 | -webkit-margin-end: 0px;
135 | font-weight: bold;
136 | }
137 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import ElementUI from 'element-ui'
5 | import 'element-ui/lib/theme-chalk/index.css'
6 | import App from './App'
7 | import router from './router'
8 | import 'styles/iconfont.css'
9 | import 'styles/swagger.css'
10 | import 'styles/tree.css'
11 | import 'styles/home.css'
12 | import 'styles/reports.css'
13 | import * as api from './restful/api'
14 | import store from './store'
15 |
16 | Vue.config.productionTip = false
17 | Vue.use(ElementUI)
18 | Vue.prototype.$api = api
19 |
20 | Vue.filter('datetimeFormat', function (time, format = 'YY-MM-DD hh:mm:ss') {
21 | let date = new Date(time);
22 | let year = date.getFullYear(),
23 | month = date.getMonth() + 1,
24 | day = date.getDate(),
25 | hour = date.getHours(),
26 | min = date.getMinutes(),
27 | sec = date.getSeconds();
28 | let preArr = Array.apply(null, Array(10)).map(function (elem, index) {
29 | return '0' + index;
30 | });
31 |
32 | let newTime = format.replace(/YY/g, year)
33 | .replace(/MM/g, preArr[month] || month)
34 | .replace(/DD/g, preArr[day] || day)
35 | .replace(/hh/g, preArr[hour] || hour)
36 | .replace(/mm/g, preArr[min] || min)
37 | .replace(/ss/g, preArr[sec] || sec);
38 |
39 | return newTime;
40 | });
41 |
42 | Vue.filter("timestampToTime", function (timestamp) {
43 | let date = new Date(timestamp * 1000);
44 | const Y = date.getFullYear() + '-';
45 | const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
46 | const D = date.getDate() + ' ';
47 | const h = date.getHours() + ':';
48 | const m = date.getMinutes() + ':';
49 | const s = date.getSeconds();
50 |
51 | return Y + M + D + h + m + s;
52 |
53 | });
54 | Vue.prototype.setLocalValue = function (name, value) {
55 | if (window.localStorage) {
56 | localStorage.setItem(name, value);
57 | } else {
58 | alert('This browser does NOT support localStorage');
59 | }
60 | };
61 | Vue.prototype.getLocalValue = function (name) {
62 | const value = localStorage.getItem(name);
63 | if (value) {
64 | return value;
65 | } else {
66 | return '';
67 | }
68 | };
69 |
70 | router.beforeEach((to, from, next) => {
71 | /* 路由发生变化修改页面title */
72 | setTimeout((res) => {
73 | if (to.meta.title) {
74 | document.title = to.meta.title
75 | }
76 |
77 | if (to.meta.requireAuth) {
78 | if (store.state.token !== '') {
79 | next();
80 | } else {
81 | next({
82 | name: 'Login',
83 | })
84 | }
85 | } else {
86 | next()
87 | }
88 | })
89 |
90 | })
91 |
92 | /* eslint-disable no-new */
93 | new Vue({
94 | el: '#app',
95 | router,
96 | store,
97 | components: {App},
98 | template: '',
99 | created() {
100 | if (this.getLocalValue("token") === null) {
101 | this.setLocalValue("token", "");
102 | }
103 | if (this.getLocalValue("user") === null) {
104 | this.setLocalValue("user", "");
105 | }
106 | if (this.getLocalValue("routerName") === null) {
107 | this.setLocalValue("routerName", "ProjectList");
108 | }
109 | this.$store.commit("isLogin", this.getLocalValue("token"));
110 | this.$store.commit("setUser", this.getLocalValue("user"));
111 | this.$store.commit("setRouterName", this.getLocalValue("routerName"));
112 |
113 | }
114 | })
115 |
--------------------------------------------------------------------------------
/src/assets/styles/home.css:
--------------------------------------------------------------------------------
1 | #form-content {
2 | width: 450px;
3 | margin: 40px auto;
4 | background-color: #FFFFFF;
5 | padding: 40px 50px;
6 | text-align: center;
7 | border-radius: 2px;
8 | -webkit-box-shadow: 0px 16px 44px 0 RGBA(0, 0, 1, 0.2);
9 | -moz-box-shadow: 0px 16px 44px 0 RGBA(0, 0, 1, 0.2);
10 | box-shadow: 0px 16px 44px 0 RGBA(0, 0, 1, 0.2);
11 | }
12 |
13 | .bottom-right {
14 | position: fixed;
15 | right: 0px;
16 | bottom: 0px;
17 | }
18 |
19 | .bottom-left {
20 | position: fixed;
21 | left: 0px;
22 | bottom: 0px;
23 | }
24 |
25 | .bottom-right img {
26 | width: 364px;
27 | height: 208px;
28 | }
29 |
30 | .bottom-left img {
31 | width: 332px;
32 | height: 271px;
33 | }
34 |
35 | img {
36 | vertical-align: middle;
37 | }
38 |
39 | img {
40 | border: 0;
41 | }
42 |
43 | .form-input-div .icon {
44 | position: relative;
45 | left: 16px;
46 | top: 8px;
47 | color: #172B4D;
48 | font-size: 18px;
49 | }
50 |
51 | .form-input-div input.has-error {
52 | border-color: #fc4949;
53 | }
54 |
55 | #form-msg {
56 | color: #172B4D;
57 | font-size: 30px;
58 | text-align: left;
59 | font-weight: 300;
60 | }
61 |
62 | .form-submit .btn-primary {
63 | width: 100%;
64 | height: 42px;
65 | font-size: 15px;
66 | color: #fff;
67 | background: #1F5DEA;
68 | border: 1px solid #1F5DEA;
69 | border-radius: 2px;
70 | }
71 |
72 | .form-foot {
73 | position: relative;
74 | margin-top: 20px;
75 | color: #A8ACB9;
76 | font-size: 12px;
77 | text-align: left;
78 | }
79 |
80 | .form-foot a, .form-foot a:hover, .form-foot a:active {
81 | color: #1F5DEA;
82 | text-decoration: none;
83 | }
84 |
85 | body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td {
86 | margin: 0;
87 | padding: 0;
88 | -webkit-box-sizing: border-box;
89 | -moz-box-sizing: border-box;
90 | box-sizing: border-box;
91 | }
92 |
93 | a:hover, a:active, a:visited, a:focus {
94 | text-decoration: none !important;
95 | cursor: pointer;
96 | }
97 |
98 | .btn:active {
99 | background: #19A8FF;
100 | }
101 |
102 | .btn {
103 | display: inline-block;
104 | padding: 6px 10px;
105 | margin-bottom: 0;
106 | font-size: 13px;
107 | font-weight: normal;
108 | line-height: 1.42857143;
109 | text-align: center;
110 | white-space: nowrap;
111 | vertical-align: middle;
112 | -ms-touch-action: manipulation;
113 | touch-action: manipulation;
114 | cursor: pointer;
115 | -webkit-user-select: none;
116 | -moz-user-select: none;
117 | -ms-user-select: none;
118 | user-select: none;
119 | background-image: none;
120 | border: 1px solid transparent;
121 | border-radius: 2px;
122 | }
123 |
124 | input, button, select, textarea {
125 | font-family: inherit;
126 | font-size: inherit;
127 | line-height: inherit;
128 | }
129 |
130 | .form-input-div input {
131 | width: 350px;
132 | height: 42px;
133 | padding-left: 39px;
134 | border: 1px solid #E1E2E6;
135 | }
136 |
137 | .err_msg {
138 | position: relative;
139 | color: #fc4949;
140 | height: 20px;
141 | line-height: 20px;
142 | }
143 |
144 | #form-inputs {
145 | width: 350px;
146 | margin-top: 30px;
147 | text-align: left;
148 | }
149 |
150 | #form-title {
151 | font-size: 40px;
152 | color: #172B4D;
153 | text-align: center;
154 | margin-top: 60px;
155 | }
156 |
157 | .login {
158 | height: 1024px;
159 | background-color: #f7f8fa;
160 | font-family: "PingFang SC", "Helvetica Neue", Helvetica, "Hiragino Sans GB", STHeitiSC-Light, "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
161 | font-size: 13px;
162 | line-height: 1.42857143;
163 | color: #333;
164 | }
165 |
--------------------------------------------------------------------------------
/src/pages/project/ProjectDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 | {{projectInfo.name}}
7 | {{projectInfo.desc}}
8 |
9 |
10 |
11 |
12 |
13 | -
14 |
{{projectInfo.api_count}} 个接口
15 | 接口总数
16 |
17 |
18 | -
19 |
{{projectInfo.case_count}} 个用例
20 | 用例集总数
21 |
22 |
23 | -
24 |
{{projectInfo.config_count}} 套配置
25 | 配置总数
26 |
27 |
28 | -
29 |
{{projectInfo.variables_count}} 对变量
30 | 全局变量对数
31 |
32 |
33 |
34 |
35 | -
36 |
{{projectInfo.host_count}} 套环境
37 | 环境总数
38 |
39 |
40 | -
41 |
{{projectInfo.task_count}} 项任务
42 | 定时任务个数
43 |
44 |
45 | -
46 |
{{projectInfo.report_count}} 个报告
47 | 测试报告总数
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
92 |
93 |
154 |
--------------------------------------------------------------------------------
/src/pages/httprunner/components/Hooks.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
135 |
136 |
138 |
--------------------------------------------------------------------------------
/src/pages/httprunner/components/Extract.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
138 |
139 |
141 |
--------------------------------------------------------------------------------
/src/pages/httprunner/DebugTalk.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 | 点击保存
15 |
16 |
17 |
24 | 在线运行
25 |
26 |
27 |
28 | 调试控制台
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
52 |
53 |
54 |
55 |
56 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
125 |
126 |
138 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Home from '@/pages/home/Home'
4 | import Register from '@/pages/auth/Register'
5 | import Login from '@/pages/auth/Login'
6 | import ProjectList from '@/pages/project/ProjectList'
7 | import ProjectDetail from '@/pages/project/ProjectDetail'
8 | import DebugTalk from '@/pages/httprunner/DebugTalk'
9 | import RecordApi from '@/pages/fastrunner/api/RecordApi'
10 | import AutoTest from '@/pages/fastrunner/case/AutoTest'
11 | import GlobalEnv from '@/pages/variables/GlobalEnv'
12 | import ReportList from '@/pages/reports/ReportList'
13 | import RecordConfig from '@/pages/fastrunner/config/RecordConfig'
14 | import Tasks from '@/pages/task/Tasks'
15 | import HostAddress from '@/pages/variables/HostAddress'
16 |
17 | Vue.use(Router);
18 |
19 | export default new Router({
20 | mode:'history',
21 | routes: [
22 | {
23 | path: '/fastrunner/register',
24 | name: 'Register',
25 | component: Register,
26 | meta: {
27 | title: '用户注册'
28 | }
29 | }, {
30 | path: '/fastrunner/login',
31 | name: 'Login',
32 | component: Login,
33 | meta: {
34 | title: '用户登录'
35 | }
36 | }, {
37 |
38 | path: '/fastrunner',
39 | name: 'Index',
40 | component: Home,
41 | meta: {
42 | title: '首页',
43 | requireAuth: true
44 | },
45 | children: [
46 | {
47 | name: 'ProjectList',
48 | path: 'project_list',
49 | component: ProjectList,
50 | meta: {
51 | title: '项目列表',
52 | requireAuth: true,
53 | }
54 | },
55 | {
56 | name: 'ProjectDetail',
57 | path: 'project/:id/dashbord',
58 | component: ProjectDetail,
59 | meta: {
60 | title: '项目预览',
61 | requireAuth: true,
62 | }
63 |
64 | },
65 | {
66 | name: 'DebugTalk',
67 | path: 'debugtalk/:id',
68 | component: DebugTalk,
69 | meta: {
70 | title: '编辑驱动',
71 | requireAuth: true,
72 | }
73 |
74 | },
75 | {
76 | name: 'RecordApi',
77 | path: 'api_record/:id',
78 | component: RecordApi,
79 | meta: {
80 | title: '接口模板',
81 | requireAuth: true
82 | }
83 |
84 | },
85 | {
86 | name: 'AutoTest',
87 | path: 'auto_test/:id',
88 | component: AutoTest,
89 | meta: {
90 | title: '自动化测试',
91 | requireAuth: true
92 | }
93 |
94 | },
95 | {
96 | name: 'RecordConfig',
97 | path: 'record_config/:id',
98 | component: RecordConfig,
99 | meta: {
100 | title: '配置管理',
101 | requireAuth: true
102 | }
103 |
104 | },
105 | {
106 | name: 'GlobalEnv',
107 | path: 'global_env/:id',
108 | component: GlobalEnv,
109 | meta: {
110 | title: '全局变量',
111 | requireAuth: true
112 | }
113 |
114 | },
115 | {
116 | name: 'Reports',
117 | path: 'reports/:id',
118 | component: ReportList,
119 | meta: {
120 | title: '历史报告',
121 | requireAuth: true
122 | }
123 |
124 | },
125 | {
126 | name: 'Task',
127 | path: 'tasks/:id',
128 | component: Tasks,
129 | meta: {
130 | title: '定时任务',
131 | requireAuth: true
132 | }
133 |
134 | },
135 | {
136 | name: 'HostIP',
137 | path: 'host_ip/:id',
138 | component: HostAddress,
139 | meta: {
140 | title: 'HOST配置',
141 | requireAuth: true
142 | }
143 |
144 | }
145 | ]
146 | },
147 |
148 | ]
149 | })
150 |
151 |
--------------------------------------------------------------------------------
/src/pages/httprunner/components/Parameters.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
15 |
16 |
23 |
24 |
25 |
26 |
29 |
30 |
37 |
38 |
39 |
40 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
150 |
151 |
153 |
--------------------------------------------------------------------------------
/src/pages/auth/components/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |

21 |
22 |
23 |
24 |
25 |
26 |
FasterRunner接口测试平台
27 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |

62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
131 |
132 |
135 |
--------------------------------------------------------------------------------
/src/pages/auth/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |

21 |
22 |
23 |
24 |
25 |
26 |
FasterRunner
27 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |

62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
129 |
130 |
133 |
--------------------------------------------------------------------------------
/src/pages/config/RecordConfig.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
163 |
164 |
168 |
--------------------------------------------------------------------------------
/src/pages/fastrunner/config/RecordConfig.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
163 |
164 |
168 |
--------------------------------------------------------------------------------
/src/pages/httprunner/components/Headers.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
15 |
16 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
214 |
215 |
217 |
--------------------------------------------------------------------------------
/src/pages/auth/Register.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |

20 |
21 |
22 |
23 |
24 |
25 |
FasterRunner
26 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |

79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
165 |
166 |
169 |
--------------------------------------------------------------------------------
/src/pages/auth/components/Register.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |

20 |
21 |
22 |
23 |
24 |
25 |
FasterRunner接口测试平台
26 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |

79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
165 |
166 |
169 |
--------------------------------------------------------------------------------
/src/pages/fastrunner/config/components/ConfigBody.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 | 配置信息录入
11 |
12 | Save
18 |
19 |
20 |
21 |
22 |
28 | 配置请求地址
29 |
30 |
31 |
32 |
33 |
37 |
38 |
42 |
43 |
44 |
45 |
46 |
51 |
52 |
53 |
54 |
55 |
60 |
61 |
62 |
63 |
64 |
65 |
70 |
71 |
72 |
73 |
74 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
223 |
224 |
240 |
--------------------------------------------------------------------------------
/src/pages/httprunner/components/Variables.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
62 |
63 |
64 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
245 |
246 |
249 |
--------------------------------------------------------------------------------
/src/pages/config/components/ConfigBody.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 | 配置信息录入
11 |
12 | Save
18 |
19 |
20 |
21 |
22 |
28 | 配置请求地址
29 |
30 |
31 |
32 |
33 |
37 |
38 |
42 |
43 |
44 |
45 |
46 |
51 |
52 |
53 |
54 |
55 |
60 |
61 |
62 |
63 |
64 |
65 |
70 |
71 |
72 |
73 |
74 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
231 |
232 |
248 |
--------------------------------------------------------------------------------
/src/pages/config/components/ConfigList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
30 |
33 |
34 |
35 |
39 |
40 | {{scope.row.name}}
41 |
42 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
58 |
59 | {{scope.row.update_time|datetimeFormat}}
60 |
61 |
62 |
63 |
64 |
67 |
68 |
69 |
75 |
76 |
82 |
83 |
84 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
225 |
226 |
231 |
--------------------------------------------------------------------------------
/src/pages/task/Tasks.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
25 |
26 |
27 |
28 |
29 |
30 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
55 |
59 |
60 | {{scope.row.name}}
61 |
62 |
63 |
64 |
65 |
69 |
70 | {{scope.row.kwargs.corntab}}
71 |
72 |
73 |
74 |
78 |
79 | {{scope.row.kwargs.strategy}}
80 |
81 |
82 |
83 |
84 |
85 |
89 |
90 |
95 |
96 |
97 |
98 |
102 |
103 | {{scope.row.kwargs.receiver}}
104 |
105 |
106 |
110 |
111 | {{scope.row.kwargs.copy}}
112 |
113 |
114 |
115 |
118 |
119 |
120 |
125 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
216 |
217 |
221 |
--------------------------------------------------------------------------------
/src/pages/reports/DebugReport.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
16 |
17 | {{scope.row.time.start_at|timestampToTime}}
18 |
19 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
35 | {{ scope.row.stat.testsRun }}
36 |
37 |
38 |
39 |
43 |
44 | {{ scope.row.stat.successes }}
45 |
46 |
47 |
48 |
52 |
53 | {{ scope.row.stat.failures }}
54 |
55 |
56 |
57 |
61 |
62 | {{ scope.row.stat.errors }}
63 |
64 |
65 |
66 |
70 |
71 | {{ scope.row.stat.skipped }}
72 |
73 |
74 |
75 |
78 |
79 |
80 | HttpRunner: {{ scope.row.platform.httprunner_version }}
81 | Python: {{ scope.row.platform.python_version }}
82 |
83 | {{ scope.row.platform.platform }}
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
{{item.name}}
97 |
102 | {{item.in_out}}
103 | parameters & output
104 |
105 |
106 |
107 |
114 |
115 |
116 |
119 |
120 | {{ scope.row.name }}
121 |
122 |
123 |
124 |
127 |
128 | {{ scope.row.meta_data.request.url }}
129 |
130 |
131 |
132 |
135 |
136 | {{ scope.row.meta_data.request.method }}
138 |
139 |
140 |
141 |
144 |
145 | {{ scope.row.meta_data.response.elapsed_ms }}
146 |
147 |
148 |
149 |
152 |
153 | {{ scope.row.status }}
154 |
155 |
156 |
157 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
227 |
228 |
231 |
--------------------------------------------------------------------------------
/src/pages/fastrunner/config/components/ConfigList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
40 |
44 |
45 |
46 |
50 |
51 | {{scope.row.name}}
52 |
53 |
54 |
55 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
69 |
70 | {{scope.row.update_time|datetimeFormat}}
71 |
72 |
73 |
74 |
75 |
78 |
79 |
80 |
86 |
87 |
93 |
94 |
95 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
242 |
243 |
247 |
--------------------------------------------------------------------------------
/src/restful/api.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import store from '../store/state'
3 | import router from '../router'
4 | import {Message} from 'element-ui';
5 |
6 |
7 |
8 | export const baseUrl = "http://localhost:8000";
9 | axios.defaults.withCredentials = true;
10 | axios.defaults.baseURL = baseUrl;
11 |
12 | axios.interceptors.request.use(function (config) {
13 | if (config.url.indexOf("/api/fastrunner/project/?cursor=") !== -1 ) {
14 | }
15 | else if (!config.url.startsWith("/api/user/")) {
16 | config.url = config.url + "?token=" + store.token;
17 | }
18 | return config;
19 | }, function (error) {
20 | return Promise.reject(error);
21 | });
22 |
23 | axios.interceptors.response.use(function (response) {
24 |
25 | return response;
26 | }, function (error) {
27 | try {
28 | if (error.response.status === 401) {
29 | router.replace({
30 | name: 'Login'
31 | })
32 | }
33 |
34 | if (error.response.status === 500) {
35 | Message.error({
36 | message: '服务器内部异常, 请检查',
37 | duration: 1000
38 | })
39 | }
40 | }
41 | catch (e) {
42 | Message.error({
43 | message: '服务器连接超时,请重试',
44 | duration: 1000
45 | })
46 | }
47 | });
48 |
49 | // user api
50 | export const register = params => {
51 | return axios.post('/api/user/register/', params).then(res => res.data)
52 | };
53 |
54 | export const login = params => {
55 | return axios.post('/api/user/login/', params).then(res => res.data)
56 | };
57 |
58 |
59 | // fastrunner api
60 | export const addProject = params => {
61 | return axios.post('/api/fastrunner/project/', params).then(res => res.data)
62 | };
63 |
64 | export const deleteProject = config => {
65 | return axios.delete('/api/fastrunner/project/', config).then(res => res.data)
66 | };
67 |
68 | export const getProjectList = params => {
69 | return axios.get('/api/fastrunner/project/').then(res => res.data)
70 | };
71 |
72 | export const getProjectDetail = pk => {
73 | return axios.get('/api/fastrunner/project/' + pk + '/').then(res => res.data)
74 | };
75 |
76 | export const getPagination = url => {
77 | return axios.get(url).then(res => res.data)
78 | };
79 |
80 | export const updateProject = params => {
81 | return axios.patch('/api/fastrunner/project/', params).then(res => res.data)
82 | };
83 |
84 | export const getDebugtalk = url => {
85 | return axios.get('/api/fastrunner/debugtalk/' + url + '/').then(res => res.data)
86 | };
87 |
88 | export const updateDebugtalk = params => {
89 | return axios.patch('/api/fastrunner/debugtalk/', params).then(res => res.data)
90 | };
91 |
92 | export const runDebugtalk = params => {
93 | return axios.post('/api/fastrunner/debugtalk/', params).then(res => res.data)
94 | };
95 |
96 | export const getTree = (url, params) => {
97 | return axios.get('/api/fastrunner/tree/' + url + '/', params).then(res => res.data)
98 | };
99 |
100 | export const updateTree = (url, params) => {
101 | return axios.patch('/api/fastrunner/tree/' + url + '/', params).then(res => res.data)
102 | };
103 |
104 | export const uploadFile = url => {
105 | return baseUrl + '/api/fastrunner/file/?token=' + store.token
106 | };
107 |
108 | export const addAPI = params => {
109 | return axios.post('/api/fastrunner/api/', params).then(res => res.data)
110 | };
111 |
112 | export const updateAPI = (url, params) => {
113 | return axios.patch('/api/fastrunner/api/' + url + '/', params).then(res => res.data)
114 | };
115 |
116 | export const apiList = params => {
117 | return axios.get('/api/fastrunner/api/', params).then(res => res.data)
118 | };
119 |
120 | export const delAPI = url => {
121 | return axios.delete('/api/fastrunner/api/' + url + '/').then(res => res.data)
122 | };
123 |
124 | export const delAllAPI = params => {
125 | return axios.delete('/api/fastrunner/api/', params).then(res => res.data)
126 | };
127 |
128 | export const getAPISingle = url => {
129 | return axios.get('/api/fastrunner/api/' + url + '/').then(res => res.data)
130 | };
131 |
132 |
133 |
134 | export const getPaginationBypage = params => {
135 | return axios.get('/api/fastrunner/api/', params).then(res => res.data)
136 | };
137 |
138 |
139 |
140 | export const addTestCase = params => {
141 | return axios.post('/api/fastrunner/test/', params).then(res => res.data)
142 | };
143 |
144 | export const updateTestCase = (url, params) => {
145 | return axios.patch('/api/fastrunner/test/' + url + '/', params).then(res => res.data)
146 | };
147 |
148 | export const testList = params => {
149 | return axios.get('/api/fastrunner/test/', params).then(res => res.data)
150 | };
151 |
152 | export const deleteTest = url => {
153 | return axios.delete('/api/fastrunner/test/' + url + '/').then(res => res.data)
154 | };
155 |
156 | export const delAllTest = params => {
157 | return axios.delete('/api/fastrunner/test/', params).then(res => res.data)
158 | };
159 |
160 | export const coptTest = (url, params) => {
161 | return axios.post('/api/fastrunner/test/' + url + '/', params).then(res => res.data)
162 | };
163 |
164 | export const editTest = url => {
165 | return axios.get('/api/fastrunner/teststep/' + url + '/').then(res => res.data)
166 | };
167 |
168 | export const getTestPaginationBypage = params => {
169 | return axios.get('/api/fastrunner/test/', params).then(res => res.data)
170 | };
171 |
172 | export const addConfig = params => {
173 | return axios.post('/api/fastrunner/config/', params).then(res => res.data)
174 | };
175 |
176 | export const updateConfig = (url, params) => {
177 | return axios.patch('/api/fastrunner/config/' + url + '/', params).then(res => res.data)
178 | };
179 |
180 |
181 | export const configList = params => {
182 | return axios.get('/api/fastrunner/config/', params).then(res => res.data)
183 | };
184 |
185 | export const copyConfig = (url, params) => {
186 | return axios.post('/api/fastrunner/config/' + url + '/', params).then(res => res.data)
187 | };
188 |
189 | export const copyAPI = (url, params) => {
190 | return axios.post('/api/fastrunner/api/' + url + '/', params).then(res => res.data)
191 | };
192 |
193 | export const deleteConfig = url => {
194 | return axios.delete('/api/fastrunner/config/' + url + '/').then(res => res.data)
195 | };
196 | export const delAllConfig = params => {
197 | return axios.delete('/api/fastrunner/config/', params).then(res => res.data)
198 | };
199 |
200 | export const getConfigPaginationBypage = params => {
201 | return axios.get('/api/fastrunner/config/', params).then(res => res.data)
202 | };
203 |
204 | export const getAllConfig = url => {
205 | return axios.get('/api/fastrunner/config/' + url + '/').then(res => res.data)
206 | };
207 |
208 |
209 | export const runSingleAPI = params => {
210 | return axios.post('/api/fastrunner/run_api/', params).then(res => res.data)
211 | };
212 |
213 | export const runAPIByPk = (url, params) => {
214 | return axios.get('/api/fastrunner/run_api_pk/' + url + '/', params).then(res => res.data)
215 | };
216 |
217 | export const runAPITree = params => {
218 | return axios.post('/api/fastrunner/run_api_tree/', params).then(res => res.data)
219 | };
220 |
221 | export const runSingleTestSuite = params => {
222 | return axios.post('/api/fastrunner/run_testsuite/', params).then(res => res.data)
223 | };
224 |
225 | export const runSingleTest = params => {
226 | return axios.post('/api/fastrunner/run_test/', params).then(res => res.data)
227 | };
228 |
229 | export const runTestByPk = (url, params) => {
230 | return axios.get('/api/fastrunner/run_testsuite_pk/' + url + '/', params).then(res => res.data)
231 | };
232 |
233 | export const runSuiteTree = params => {
234 | return axios.post('/api/fastrunner/run_suite_tree/', params).then(res => res.data)
235 | };
236 |
237 | export const addVariables = params => {
238 | return axios.post('/api/fastrunner/variables/', params).then(res => res.data)
239 | };
240 |
241 | export const variablesList = params => {
242 | return axios.get('/api/fastrunner/variables/', params).then(res => res.data)
243 | };
244 |
245 | export const getVariablesPaginationBypage = params => {
246 | return axios.get('/api/fastrunner/variables/', params).then(res => res.data)
247 | };
248 |
249 |
250 | export const updateVariables = (url, params) => {
251 | return axios.patch('/api/fastrunner/variables/' + url + '/', params).then(res => res.data)
252 | };
253 |
254 | export const deleteVariables = url => {
255 | return axios.delete('/api/fastrunner/variables/' + url + '/').then(res => res.data)
256 | };
257 |
258 | export const delAllVariabels = params => {
259 | return axios.delete('/api/fastrunner/variables/', params).then(res => res.data)
260 | };
261 |
262 | export const reportList = params => {
263 | return axios.get('/api/fastrunner/reports/', params).then(res => res.data)
264 | };
265 |
266 | export const deleteReports = url => {
267 | return axios.delete('/api/fastrunner/reports/' + url + '/').then(res => res.data)
268 | };
269 |
270 | export const getReportsPaginationBypage = params => {
271 | return axios.get('/api/fastrunner/reports/', params).then(res => res.data)
272 | };
273 |
274 | export const delAllReports = params => {
275 | return axios.delete('/api/fastrunner/reports/', params).then(res => res.data)
276 | };
277 |
278 | export const watchSingleReports = url => {
279 | return axios.get('/api/fastrunner/reports/' + url + '/').then(res => res.data)
280 | };
281 |
282 | export const addTask = params => {
283 | return axios.post('/api/fastrunner/schedule/', params).then(res => res.data)
284 | };
285 | export const taskList = params => {
286 | return axios.get('/api/fastrunner/schedule/', params).then(res => res.data)
287 | };
288 | export const getTaskPaginationBypage = params => {
289 | return axios.get('/api/fastrunner/schedule/', params).then(res => res.data)
290 | };
291 | export const deleteTasks = url => {
292 | return axios.delete('/api/fastrunner/schedule/' + url + '/').then(res => res.data)
293 | };
294 |
295 | export const addHostIP = params => {
296 | return axios.post('/api/fastrunner/host_ip/', params).then(res => res.data)
297 | };
298 |
299 | export const hostList = params => {
300 | return axios.get('/api/fastrunner/host_ip/', params).then(res => res.data)
301 | };
302 |
303 | export const updateHost = (url, params) => {
304 | return axios.patch('/api/fastrunner/host_ip/' + url + '/', params).then(res => res.data)
305 | };
306 |
307 | export const deleteHost = url => {
308 | return axios.delete('/api/fastrunner/host_ip/' + url + '/').then(res => res.data)
309 | };
310 |
311 | export const getHostPaginationBypage = params => {
312 | return axios.get('/api/fastrunner/host_ip/', params).then(res => res.data)
313 | };
314 |
315 | export const getAllHost = url => {
316 | return axios.get('/api/fastrunner/host_ip/' + url + '/').then(res => res.data)
317 | };
318 |
319 |
--------------------------------------------------------------------------------
/src/pages/httprunner/components/Validate.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
15 |
16 |
22 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
50 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
78 |
79 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
307 |
308 |
310 |
--------------------------------------------------------------------------------
/src/assets/styles/iconfont.css:
--------------------------------------------------------------------------------
1 | @font-face {font-family: "iconfont";
2 | src: url('./icon-font/iconfont.eot?t=1551323395845'); /* IE9 */
3 | src: url('./icon-font/iconfont.eot?t=1551323395845#iefix') format('embedded-opentype'), /* IE6-IE8 */
4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
5 | url('./icon-font/iconfont.woff?t=1551323395845') format('woff'),
6 | url('./icon-font/iconfont.ttf?t=1551323395845') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
7 | url('./icon-font/iconfont.svg?t=1551323395845#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family: "iconfont" !important;
12 | font-size: 16px;
13 | font-style: normal;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | .icon-youxiang:before {
19 | content: "\e668";
20 | }
21 |
22 | .icon-baogao:before {
23 | content: "\e66e";
24 | }
25 |
26 | .icon-ybbindex:before {
27 | content: "\e631";
28 | }
29 |
30 | .icon-02:before {
31 | content: "\e64a";
32 | }
33 |
34 | .icon-iconset0196:before {
35 | content: "\e65f";
36 | }
37 |
38 | .icon-17:before {
39 | content: "\e610";
40 | }
41 |
42 | .icon-xiazai:before {
43 | content: "\e600";
44 | }
45 |
46 | .icon-index:before {
47 | content: "\e66d";
48 | }
49 |
50 | .icon-fuzhifuzhi:before {
51 | content: "\e636";
52 | }
53 |
54 | .icon-debug:before {
55 | content: "\e606";
56 | }
57 |
58 | .icon-shijian:before {
59 | content: "\e63b";
60 | }
61 |
62 | .icon-language-python-text:before {
63 | content: "\e7ca";
64 | }
65 |
66 | .icon-xiangmu:before {
67 | content: "\e63c";
68 | }
69 |
70 | .icon-jiankong:before {
71 | content: "\e61f";
72 | }
73 |
74 | .icon-houtui:before {
75 | content: "\e617";
76 | }
77 |
78 | .icon-dingshirenwu:before {
79 | content: "\e61e";
80 | }
81 |
82 | .icon-xiangmu1:before {
83 | content: "\e707";
84 | }
85 |
86 | .icon-ceshi:before {
87 | content: "\e6da";
88 | }
89 |
90 | .icon-mima:before {
91 | content: "\e652";
92 | }
93 |
94 | .icon-quanju_yuming:before {
95 | content: "\e609";
96 | }
97 |
98 | .icon-jiekou:before {
99 | content: "\e74a";
100 | }
101 |
102 | .icon-shujuku:before {
103 | content: "\e615";
104 | }
105 |
106 | .icon-yali:before {
107 | content: "\e632";
108 | }
109 |
110 | .icon-xingmingyonghumingnicheng:before {
111 | content: "\e61c";
112 | }
113 |
114 | .icon-xiugai:before {
115 | content: "\e67d";
116 | }
117 |
118 | .icon-houtui1:before {
119 | content: "\e66f";
120 | }
121 |
122 | .icon-yumingguanli:before {
123 | content: "\e6cc";
124 | }
125 |
126 | .icon-yonghuming:before {
127 | content: "\e60d";
128 | }
129 |
130 | .icon-houtui2:before {
131 | content: "\e613";
132 | }
133 |
134 | .icon-171:before {
135 | content: "\e601";
136 | }
137 |
138 | .icon-bendibianliang:before {
139 | content: "\e692";
140 | }
141 |
142 | .icon-youxiang1:before {
143 | content: "\e650";
144 | }
145 |
146 | .icon-config:before {
147 | content: "\ee32";
148 | }
149 |
150 | .icon-fuzhi:before {
151 | content: "\e63d";
152 | }
153 |
154 | .icon-shujuku1:before {
155 | content: "\e782";
156 | }
157 |
158 | .icon-xiangmuliebiao:before {
159 | content: "\e7a7";
160 | }
161 |
162 | .icon-python:before {
163 | content: "\f216";
164 | }
165 |
166 | .icon-yunhang:before {
167 | content: "\e616";
168 | }
169 |
170 | .icon-shanchu:before {
171 | content: "\e608";
172 | }
173 |
174 | .icon-xiazai1:before {
175 | content: "\e602";
176 | }
177 |
178 |
--------------------------------------------------------------------------------
/src/pages/fastrunner/case/components/TestBody.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 | 接口信息录入
12 |
13 | Save
19 |
20 |
21 |
22 |
23 | Back
28 |
29 |
30 |
36 |
37 |
38 |
39 |
40 |
46 |
51 |
57 |
58 |
59 |
60 |
61 |
66 |
73 |
74 |
75 |
76 |
81 |
82 |
83 |
84 |
85 |
86 |
90 |
91 |
96 |
97 |
98 |
99 |
100 |
105 |
106 |
107 |
108 |
109 |
114 |
115 |
116 |
117 |
118 |
123 |
124 |
125 |
126 |
127 |
128 |
133 |
134 |
135 |
136 |
137 |
138 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
309 |
310 |
326 |
--------------------------------------------------------------------------------
/src/pages/project/ProjectList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 | 添加项目
11 |
12 |
13 |
21 | 上一页
22 |
23 |
24 |
30 | 下一页
31 |
32 |
33 |
34 |
35 |
41 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
73 |
78 |
79 | {{ scope.row.name }}
83 |
84 |
85 |
86 |
91 |
92 | {{ scope.row.responsible }}
93 |
94 |
95 |
96 |
101 |
102 | {{ scope.row.desc }}
103 |
104 |
105 |
106 |
111 |
112 | {{ scope.row.update_time | datetimeFormat }}
113 |
114 |
115 |
116 |
117 |
121 |
122 | 详情
125 |
126 |
127 | 编辑
131 |
132 |
133 |
138 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
154 |
155 | 删除
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
291 |
292 |
295 |
--------------------------------------------------------------------------------