Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
d0ddd8d8
M
metersphere
项目概览
MeterSphere
/
metersphere
上一次同步 大约 3 年
通知
25
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
metersphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d0ddd8d8
编写于
4月 23, 2020
作者:
C
Captain.B
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/dev' into dev
上级
cebfba84
618ab09d
变更
31
隐藏空白更改
内联
并排
Showing
31 changed file
with
518 addition
and
465 deletion
+518
-465
backend/src/main/java/io/metersphere/api/controller/APITestController.java
...java/io/metersphere/api/controller/APITestController.java
+5
-5
backend/src/main/java/io/metersphere/api/service/ApiTestService.java
.../main/java/io/metersphere/api/service/ApiTestService.java
+4
-0
frontend/package.json
frontend/package.json
+5
-4
frontend/src/business/App.vue
frontend/src/business/App.vue
+10
-7
frontend/src/business/components/api/test/ApiTestConfig.vue
frontend/src/business/components/api/test/ApiTestConfig.vue
+40
-19
frontend/src/business/components/api/test/ApiTestList.vue
frontend/src/business/components/api/test/ApiTestList.vue
+15
-19
frontend/src/business/components/api/test/model/ScenarioModel.js
...d/src/business/components/api/test/model/ScenarioModel.js
+63
-63
frontend/src/business/components/common/components/MsTableOperator.vue
...business/components/common/components/MsTableOperator.vue
+35
-0
frontend/src/business/components/common/components/MsTableOperatorButton.vue
...ss/components/common/components/MsTableOperatorButton.vue
+34
-0
frontend/src/business/components/common/head/RecentList.vue
frontend/src/business/components/common/head/RecentList.vue
+26
-8
frontend/src/business/components/common/router/router.js
frontend/src/business/components/common/router/router.js
+1
-1
frontend/src/business/components/project/MsProject.vue
frontend/src/business/components/project/MsProject.vue
+3
-3
frontend/src/business/components/settings/organization/OrganizationWorkspace.vue
...omponents/settings/organization/OrganizationWorkspace.vue
+6
-13
frontend/src/business/components/settings/system/Organization.vue
.../src/business/components/settings/system/Organization.vue
+6
-13
frontend/src/business/components/settings/system/SystemWorkspace.vue
...c/business/components/settings/system/SystemWorkspace.vue
+6
-13
frontend/src/business/components/settings/workspace/WorkspaceMember.vue
...usiness/components/settings/workspace/WorkspaceMember.vue
+1
-1
frontend/src/business/components/track/case/components/TestCaseList.vue
...usiness/components/track/case/components/TestCaseList.vue
+55
-19
frontend/src/business/components/track/common/PlanNodeTree.vue
...end/src/business/components/track/common/PlanNodeTree.vue
+0
-183
frontend/src/business/components/track/common/TableItems/MethodTableItem.vue
...ss/components/track/common/TableItems/MethodTableItem.vue
+21
-0
frontend/src/business/components/track/common/TableItems/PriorityTableItem.vue
.../components/track/common/TableItems/PriorityTableItem.vue
+36
-0
frontend/src/business/components/track/common/TableItems/StatusTableItem.vue
...ss/components/track/common/TableItems/StatusTableItem.vue
+39
-0
frontend/src/business/components/track/common/TableItems/TypeTableItem.vue
...ness/components/track/common/TableItems/TypeTableItem.vue
+24
-0
frontend/src/business/components/track/plan/TestPlan.vue
frontend/src/business/components/track/plan/TestPlan.vue
+1
-0
frontend/src/business/components/track/plan/components/TestPlanList.vue
...usiness/components/track/plan/components/TestPlanList.vue
+10
-29
frontend/src/business/components/track/plan/view/TestPlanView.vue
.../src/business/components/track/plan/view/TestPlanView.vue
+4
-4
frontend/src/business/components/track/plan/view/comonents/ExecutorEdit.vue
...ess/components/track/plan/view/comonents/ExecutorEdit.vue
+2
-2
frontend/src/business/components/track/plan/view/comonents/StatusEdit.vue
...iness/components/track/plan/view/comonents/StatusEdit.vue
+2
-2
frontend/src/business/components/track/plan/view/comonents/TestCaseRelevance.vue
...omponents/track/plan/view/comonents/TestCaseRelevance.vue
+2
-2
frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue
...onents/track/plan/view/comonents/TestPlanTestCaseEdit.vue
+1
-1
frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseList.vue
...onents/track/plan/view/comonents/TestPlanTestCaseList.vue
+60
-54
frontend/src/i18n/zh-CN.js
frontend/src/i18n/zh-CN.js
+1
-0
未找到文件。
backend/src/main/java/io/metersphere/api/controller/APITestController.java
浏览文件 @
d0ddd8d8
...
...
@@ -60,9 +60,9 @@ public class APITestController {
public
void
delete
(
@RequestBody
DeleteAPITestRequest
request
)
{
apiTestService
.
delete
(
request
);
}
//
//
@PostMapping("/run")
// public void run(@RequestBody RunTestPlan
Request request) {
//
apiTestService.run(request);
//
}
@PostMapping
(
"/run"
)
public
void
run
(
@RequestBody
SaveAPITest
Request
request
)
{
apiTestService
.
run
(
request
);
}
}
backend/src/main/java/io/metersphere/api/service/ApiTestService.java
浏览文件 @
d0ddd8d8
...
...
@@ -66,6 +66,10 @@ public class ApiTestService {
apiTestMapper
.
deleteByPrimaryKey
(
request
.
getId
());
}
public
void
run
(
SaveAPITestRequest
request
)
{
save
(
request
);
}
private
ApiTestWithBLOBs
updateTest
(
SaveAPITestRequest
request
)
{
final
ApiTestWithBLOBs
test
=
new
ApiTestWithBLOBs
();
test
.
setId
(
request
.
getId
());
...
...
frontend/package.json
浏览文件 @
d0ddd8d8
...
...
@@ -14,13 +14,14 @@
"@fortawesome/vue-fontawesome"
:
"^0.1.9"
,
"axios"
:
"^0.19.0"
,
"core-js"
:
"^3.4.3"
,
"echarts"
:
"^4.6.0"
,
"element-ui"
:
"^2.13.0"
,
"vue"
:
"^2.6.10"
,
"vue-echarts"
:
"^4.1.0"
,
"vue-i18n"
:
"^8.15.3"
,
"vue-router"
:
"^3.1.3"
,
"vuex"
:
"^3.1.2"
,
"echarts"
:
"^4.6.0"
,
"vue-echarts"
:
"^4.1.0"
"vuedraggable"
:
"^2.23.2"
,
"vuex"
:
"^3.1.2"
},
"devDependencies"
:
{
"@vue/cli-plugin-babel"
:
"^4.1.0"
,
...
...
@@ -42,7 +43,7 @@
],
"rules"
:
{
"vue/no-unused-components"
:
"off"
,
"no-console"
:
"off"
,
"no-console"
:
"off"
,
"no-unused-vars"
:
"off"
},
"parserOptions"
:
{
...
...
frontend/src/business/App.vue
浏览文件 @
d0ddd8d8
<
template
>
<el-col
v-if=
"auth"
>
<el-row
id=
"header-top"
type=
"flex"
justify=
"space-between"
align=
"middle"
>
<el-col
:span=
"2"
>
<el-col
:span=
"12"
>
<a
class=
"logo"
/>
</el-col>
<el-col
:span=
"10"
>
<ms-top-menus/>
</el-col>
<el-col
:span=
"12"
>
<ms-user/>
</el-col>
</el-row>
<ms-view/>
<ms-web-socket/>
</el-col>
</
template
>
...
...
@@ -21,7 +20,6 @@
import
MsTopMenus
from
"
./components/common/head/HeaderTopMenus
"
;
import
MsView
from
"
./components/common/router/View
"
;
import
MsUser
from
"
./components/common/head/HeaderUser
"
;
import
MsWebSocket
from
"
./components/common/websocket/WebSocket
"
;
export
default
{
name
:
'
app
'
,
...
...
@@ -33,7 +31,6 @@
beforeCreate
()
{
this
.
$get
(
"
/isLogin
"
).
then
(
response
=>
{
if
(
response
.
data
.
success
)
{
window
.
console
.
log
(
response
.
data
);
this
.
$setLang
(
response
.
data
.
data
);
this
.
auth
=
true
;
}
else
{
...
...
@@ -43,7 +40,7 @@
window
.
location
.
href
=
"
/login
"
});
},
components
:
{
Ms
WebSocket
,
Ms
User
,
MsView
,
MsTopMenus
},
components
:
{
MsUser
,
MsView
,
MsTopMenus
},
methods
:
{}
}
</
script
>
...
...
@@ -62,6 +59,7 @@
width
:
156px
;
margin-right
:
20px
;
display
:
inline-block
;
line-height
:
40px
;
background-size
:
156px
30px
;
height
:
40px
;
background-repeat
:
no-repeat
;
...
...
@@ -78,6 +76,11 @@
line-height
:
40px
;
}
.header-top-menus
{
display
:
inline-block
;
border
:
0
;
}
.menus
>
a
{
padding-right
:
15px
;
text-decoration
:
none
;
...
...
frontend/src/business/components/api/test/ApiTestConfig.vue
浏览文件 @
d0ddd8d8
...
...
@@ -11,7 +11,15 @@
<el-option
v-for=
"project in projects"
:key=
"project.id"
:label=
"project.name"
:value=
"project.id"
/>
</el-select>
</el-input>
<el-button
type=
"primary"
plain
:disabled=
"isDisabled"
@
click=
"saveTest"
>
保存
</el-button>
<el-button
type=
"primary"
plain
:disabled=
"isDisabled"
@
click=
"saveTest"
>
{{
$t
(
'
commons.save
'
)
}}
</el-button>
<el-button
type=
"primary"
plain
:disabled=
"isDisabled"
@
click=
"runTest"
>
{{
$t
(
'
load_test.save_and_run
'
)
}}
</el-button>
<el-button
type=
"warning"
plain
@
click=
"clear"
>
{{
$t
(
'
commons.cancel
'
)
}}
</el-button>
</el-row>
</el-header>
<ms-api-scenario-config
:scenarios=
"test.scenarioDefinition"
ref=
"config"
/>
...
...
@@ -41,17 +49,15 @@
}
},
beforeRouteUpdate
(
to
,
from
,
next
)
{
if
(
to
.
params
.
type
===
"
edit
"
)
{
this
.
getTest
(
to
.
query
.
id
);
}
else
{
this
.
test
=
new
Test
();
this
.
$refs
.
config
.
reset
();
}
next
();
},
watch
:
{
'
$route
'
(
to
)
{
if
(
to
.
query
.
id
)
{
this
.
getTest
(
to
.
query
.
id
);
}
else
{
this
.
test
=
new
Test
();
this
.
$refs
.
config
.
reset
();
}
},
test
:
{
handler
:
function
()
{
this
.
change
=
true
;
...
...
@@ -65,7 +71,7 @@
this
.
result
=
this
.
$get
(
"
/api/get/
"
+
id
,
response
=>
{
let
item
=
response
.
data
;
this
.
test
.
rese
t
({
this
.
test
=
new
Tes
t
({
id
:
item
.
id
,
projectId
:
item
.
projectId
,
name
:
item
.
name
,
...
...
@@ -77,20 +83,35 @@
saveTest
:
function
()
{
this
.
change
=
false
;
let
param
=
{
id
:
this
.
test
.
id
,
projectId
:
this
.
test
.
projectId
,
name
:
this
.
test
.
name
,
scenarioDefinition
:
JSON
.
stringify
(
this
.
test
.
scenarioDefinition
)
}
this
.
result
=
this
.
$post
(
"
/api/save
"
,
this
.
getParam
(),
response
=>
{
this
.
test
.
id
=
response
.
data
;
this
.
$message
({
message
:
this
.
$t
(
'
commons.save_success
'
),
type
:
'
success
'
});
});
},
runTest
:
function
()
{
this
.
change
=
false
;
this
.
result
=
this
.
$post
(
"
/api/
save
"
,
param
,
response
=>
{
this
.
result
=
this
.
$post
(
"
/api/
run
"
,
this
.
getParam
()
,
response
=>
{
this
.
test
.
id
=
response
.
data
;
this
.
$message
({
message
:
this
.
$t
(
'
commons.save_success
'
),
type
:
'
success
'
});
});
},
clear
:
function
()
{
this
.
test
=
new
Test
();
},
getParam
:
function
()
{
return
{
id
:
this
.
test
.
id
,
projectId
:
this
.
test
.
projectId
,
name
:
this
.
test
.
name
,
scenarioDefinition
:
JSON
.
stringify
(
this
.
test
.
scenarioDefinition
)
}
}
},
...
...
frontend/src/business/components/api/test/ApiTestList.vue
浏览文件 @
d0ddd8d8
...
...
@@ -3,17 +3,8 @@
<div
class=
"main-content"
>
<el-card>
<template
v-slot:header
>
<div>
<el-row
type=
"flex"
justify=
"space-between"
align=
"middle"
>
<span
class=
"title"
>
{{
$t
(
'
commons.test
'
)
}}
</span>
<span
class=
"search"
>
<el-input
type=
"text"
size=
"small"
:placeholder=
"$t('load_test.search_by_name')"
prefix-icon=
"el-icon-search"
maxlength=
"60"
v-model=
"condition"
@
change=
"search"
clearable
/>
</span>
</el-row>
</div>
<ms-table-header
:condition.sync=
"condition"
@
search=
"search"
:title=
"$t('commons.test')"
@
create=
"create"
:createTip=
"$t('load_test.create')"
/>
</
template
>
<el-table
:data=
"tableData"
class=
"test-content"
>
<el-table-column
...
...
@@ -65,13 +56,14 @@
<
script
>
import
MsTablePagination
from
"
../../common/pagination/TablePagination
"
;
import
MsTableHeader
from
"
../../common/components/MsTableHeader
"
;
export
default
{
components
:
{
MsTablePagination
},
components
:
{
MsTable
Header
,
MsTable
Pagination
},
data
()
{
return
{
result
:
{},
condition
:
""
,
condition
:
{
name
:
""
}
,
projectId
:
null
,
tableData
:
[],
multipleSelection
:
[],
...
...
@@ -83,10 +75,11 @@
}
},
beforeRouteUpdate
(
to
,
from
,
next
)
{
this
.
projectId
=
to
.
params
.
projectId
;
this
.
search
();
next
();
watch
:
{
'
$route
'
(
to
)
{
this
.
projectId
=
to
.
params
.
projectId
;
this
.
search
();
}
},
created
:
function
()
{
...
...
@@ -95,9 +88,12 @@
},
methods
:
{
create
()
{
this
.
$router
.
push
(
'
/api/test/create
'
);
},
search
()
{
let
param
=
{
name
:
this
.
condition
,
name
:
this
.
condition
.
name
,
};
if
(
this
.
projectId
!==
'
all
'
)
{
...
...
@@ -129,7 +125,7 @@
message
:
this
.
$t
(
'
commons.delete_success
'
),
type
:
'
success
'
});
this
.
initTableData
();
this
.
search
();
});
}
}
...
...
frontend/src/business/components/api/test/model/ScenarioModel.js
浏览文件 @
d0ddd8d8
import
{
generateId
}
from
"
element-ui/src/utils/util
"
;
const
assign
=
function
(
obj
,
options
)
{
if
(
options
)
{
for
(
let
name
in
options
)
{
if
(
options
.
hasOwnProperty
(
name
))
{
if
(
!
(
obj
[
name
]
instanceof
Array
))
{
obj
[
name
]
=
options
[
name
];
}
}
}
}
}
const
assigns
=
function
(
target
,
source
,
type
)
{
if
(
target
instanceof
Array
&&
source
instanceof
Array
)
{
if
(
source
&&
source
.
length
>
0
)
{
source
.
forEach
((
options
)
=>
{
target
.
push
(
new
type
(
options
));
})
}
}
}
export
const
BODY_TYPE
=
{
KV
:
"
KV
"
,
TEXT
:
"
TEXT
"
...
...
@@ -33,54 +11,80 @@ export const ASSERTION_TYPE = {
RESPONSE_TIME
:
"
RESPONSE_TIME
"
}
export
class
Test
{
constructor
(
options
)
{
this
.
reset
(
options
);
class
BaseConfig
{
set
(
options
)
{
options
=
this
.
initOptions
(
options
)
for
(
let
name
in
options
)
{
if
(
options
.
hasOwnProperty
(
name
))
{
if
(
!
(
this
[
name
]
instanceof
Array
))
{
this
[
name
]
=
options
[
name
];
}
}
}
}
reset
(
options
)
{
options
=
this
.
getDefaultOptions
(
options
);
sets
(
types
,
options
)
{
options
=
this
.
initOptions
(
options
)
if
(
types
)
{
for
(
let
name
in
types
)
{
if
(
types
.
hasOwnProperty
(
name
)
&&
options
.
hasOwnProperty
(
name
))
{
options
[
name
].
forEach
((
o
)
=>
{
this
[
name
].
push
(
new
types
[
name
](
o
));
})
}
}
}
}
initOptions
(
options
)
{
return
options
||
{};
}
}
export
class
Test
extends
BaseConfig
{
constructor
(
options
)
{
super
();
this
.
id
=
null
;
this
.
name
=
null
;
this
.
projectId
=
null
;
this
.
scenarioDefinition
=
[];
assign
(
this
,
options
);
assigns
(
this
.
scenarioDefinition
,
options
.
scenarioDefinition
,
Scenario
);
this
.
set
(
options
);
this
.
sets
({
scenarioDefinition
:
Scenario
},
options
);
}
getDefaul
tOptions
(
options
)
{
ini
tOptions
(
options
)
{
options
=
options
||
{};
options
.
scenarioDefinition
=
options
.
scenarioDefinition
||
[
new
Scenario
()];
return
options
;
}
}
export
class
Scenario
{
export
class
Scenario
extends
BaseConfig
{
constructor
(
options
)
{
options
=
this
.
getDefaultOptions
(
options
);
super
(
);
this
.
name
=
null
;
this
.
url
=
null
;
this
.
variables
=
[];
this
.
headers
=
[];
this
.
requests
=
[];
assign
(
this
,
options
);
assigns
(
this
.
variables
,
options
.
variables
,
KeyValue
);
assigns
(
this
.
headers
,
options
.
headers
,
KeyValue
);
assigns
(
this
.
requests
,
options
.
requests
,
Request
);
this
.
set
(
options
);
this
.
sets
({
variables
:
KeyValue
,
headers
:
KeyValue
,
requests
:
Request
},
options
);
}
getDefaul
tOptions
(
options
)
{
ini
tOptions
(
options
)
{
options
=
options
||
{};
options
.
requests
=
options
.
requests
||
[
new
Request
()];
return
options
;
}
}
export
class
Request
{
export
class
Request
extends
BaseConfig
{
constructor
(
options
)
{
options
=
this
.
getDefaultOptions
(
options
);
super
(
);
this
.
randomId
=
generateId
();
this
.
name
=
null
;
this
.
url
=
null
;
...
...
@@ -91,13 +95,12 @@ export class Request {
this
.
assertions
=
null
;
this
.
extract
=
[];
assign
(
this
,
options
);
assigns
(
this
.
parameters
,
options
.
parameters
,
KeyValue
);
assigns
(
this
.
headers
,
options
.
headers
,
KeyValue
);
this
.
set
(
options
);
this
.
sets
({
parameters
:
KeyValue
,
headers
:
KeyValue
},
options
);
// TODO assigns extract
}
getDefaul
tOptions
(
options
)
{
ini
tOptions
(
options
)
{
options
=
options
||
{};
options
.
method
=
"
GET
"
;
options
.
body
=
new
Body
(
options
.
body
);
...
...
@@ -106,15 +109,15 @@ export class Request {
}
}
export
class
Body
{
export
class
Body
extends
BaseConfig
{
constructor
(
options
)
{
options
=
options
||
{}
;
super
()
;
this
.
type
=
null
;
this
.
text
=
null
;
this
.
kvs
=
[];
assign
(
this
,
options
);
assigns
(
this
.
kvs
,
options
.
kvs
,
KeyValue
);
this
.
set
(
options
);
this
.
sets
({
kvs
:
KeyValue
},
options
);
}
isKV
()
{
...
...
@@ -122,72 +125,69 @@ export class Body {
}
}
export
class
KeyValue
{
export
class
KeyValue
extends
BaseConfig
{
constructor
(
options
)
{
options
=
options
||
{}
;
super
()
;
this
.
key
=
null
;
this
.
value
=
null
;
assign
(
this
,
options
);
this
.
set
(
options
);
}
}
export
class
Assertions
{
export
class
Assertions
extends
BaseConfig
{
constructor
(
options
)
{
options
=
this
.
getDefaultOptions
(
options
);
super
(
);
this
.
text
=
[];
this
.
regex
=
[];
this
.
responseTime
=
null
;
assign
(
this
,
options
);
assigns
(
this
.
text
,
options
.
text
,
KeyValue
);
assigns
(
this
.
regex
,
options
.
regex
,
KeyValue
);
this
.
set
(
options
);
this
.
sets
({
text
:
KeyValue
,
regex
:
KeyValue
},
options
);
}
getDefaul
tOptions
(
options
)
{
ini
tOptions
(
options
)
{
options
=
options
||
{};
options
.
responseTime
=
new
ResponseTime
(
options
.
responseTime
);
return
options
;
}
}
class
AssertionType
{
class
AssertionType
extends
BaseConfig
{
constructor
(
type
)
{
super
();
this
.
type
=
type
;
}
}
export
class
Text
extends
AssertionType
{
constructor
(
options
)
{
options
=
options
||
{};
super
(
ASSERTION_TYPE
.
TEXT
);
this
.
subject
=
null
;
this
.
condition
=
null
;
this
.
value
=
null
;
assign
(
this
,
options
);
this
.
set
(
options
);
}
}
export
class
Regex
extends
AssertionType
{
constructor
(
options
)
{
options
=
options
||
{};
super
(
ASSERTION_TYPE
.
REGEX
);
this
.
subject
=
null
;
this
.
expression
=
null
;
this
.
description
=
null
;
assign
(
this
,
options
);
this
.
set
(
options
);
}
}
export
class
ResponseTime
extends
AssertionType
{
constructor
(
options
)
{
options
=
options
||
{};
super
(
ASSERTION_TYPE
.
RESPONSE_TIME
);
this
.
responseInTime
=
null
;
assign
(
this
,
options
);
this
.
set
(
options
);
}
}
frontend/src/business/components/common/components/MsTableOperator.vue
0 → 100644
浏览文件 @
d0ddd8d8
<
template
>
<span>
<ms-table-operator-button
icon=
"el-icon-edit"
@
click=
"editClick"
@
click.stop=
"editClickStop"
/>
<ms-table-operator-button
icon=
"el-icon-delete"
type=
"danger"
@
click=
"deletClick"
@
click.stop=
"deleteClickStop"
/>
</span>
</
template
>
<
script
>
import
MsTableOperatorButton
from
"
./MsTableOperatorButton
"
;
export
default
{
name
:
"
MsTableOperator
"
,
components
:
{
MsTableOperatorButton
},
methods
:
{
editClick
()
{
this
.
$emit
(
'
editClick
'
);
},
editClickStop
()
{
this
.
$emit
(
'
editClickStop
'
);
},
deletClick
()
{
this
.
$emit
(
'
deleteClick
'
);
},
deleteClickStop
()
{
this
.
$emit
(
'
deleteClickStop
'
);
}
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/common/components/MsTableOperatorButton.vue
0 → 100644
浏览文件 @
d0ddd8d8
<
template
>
<el-button
@
click=
"click"
@
click.stop=
"clickStop"
:type=
"type"
:icon=
"icon"
size=
"mini"
circle
/>
</
template
>
<
script
>
import
MsTableButton
from
"
./MsTableButton
"
;
export
default
{
name
:
"
MsTableOperatorButton
"
,
components
:
{
MsTableButton
},
props
:
{
icon
:
{
type
:
String
,
default
:
'
el-icon-question
'
},
type
:
{
type
:
String
,
default
:
'
primary
'
}
},
methods
:
{
click
()
{
this
.
$emit
(
'
click
'
);
},
clickStop
()
{
this
.
$emit
(
'
clickStop
'
);
}
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/common/head/RecentList.vue
浏览文件 @
d0ddd8d8
<
template
>
<div>
<div
v-loading=
"result.loading"
>
<div
class=
"recent-text"
>
<i
class=
"el-icon-time"
/>
<span>
{{
options
.
title
}}
</span>
<i
class=
"el-icon-refresh"
@
click=
"recent"
/>
</div>
<el-menu-item
:key=
"i.id"
v-for=
"i in items"
:index=
"getIndex(i)"
:route=
"getRouter(i)"
>
<el-menu-item
:key=
"i.id"
v-for=
"i in items"
:index=
"getIndex(i)"
:route=
"getRouter(i)"
>
<span
class=
"title"
>
{{
i
.
name
}}
</span>
</el-menu-item>
</div>
...
...
@@ -21,14 +21,11 @@
options
:
Object
},
mounted
()
{
if
(
hasRoles
(
ROLE_TEST_VIEWER
,
ROLE_TEST_USER
,
ROLE_TEST_MANAGER
))
{
this
.
$get
(
this
.
options
.
url
,
(
response
)
=>
{
this
.
items
=
response
.
data
;
});
}
this
.
recent
();
},
data
()
{
return
{
result
:
{},
items
:
[]
}
},
...
...
@@ -45,6 +42,16 @@
}
}
}
},
methods
:
{
recent
:
function
()
{
if
(
hasRoles
(
ROLE_TEST_VIEWER
,
ROLE_TEST_USER
,
ROLE_TEST_MANAGER
))
{
this
.
result
=
this
.
$get
(
this
.
options
.
url
,
(
response
)
=>
{
this
.
items
=
response
.
data
;
});
}
}
}
}
</
script
>
...
...
@@ -60,6 +67,17 @@
.recent-text
span
{
padding-left
:
6px
;
line-height
:
36px
;
}
.recent-text
.el-icon-refresh
{
cursor
:
pointer
;
float
:
right
;
line-height
:
36px
;
}
.recent-text
.el-icon-refresh
:hover
{
color
:
#BBBBBB
;
}
.title
{
...
...
frontend/src/business/components/common/router/router.js
浏览文件 @
d0ddd8d8
...
...
@@ -26,7 +26,7 @@ import PerformanceReportView from "../../performance/report/PerformanceReportVie
import
ApiReportView
from
"
../../api/report/ApiReportView
"
;
import
TrackHome
from
"
../../track/home/TrackHome
"
;
import
TestPlan
from
"
../../track/plan/TestPlan
"
;
import
TestPlanView
from
"
../../track/plan/TestPlanView
"
;
import
TestPlanView
from
"
../../track/plan/
view/
TestPlanView
"
;
import
TestCase
from
"
../../track/case/TestCase
"
;
import
TestTrack
from
"
../../track/TestTrack
"
;
...
...
frontend/src/business/components/project/MsProject.vue
浏览文件 @
d0ddd8d8
...
...
@@ -12,8 +12,7 @@
<el-table-column
prop=
"workspaceName"
label=
"所属工作空间"
/>
<el-table-column>
<
template
v-slot:default=
"scope"
>
<el-button
@
click=
"edit(scope.row)"
type=
"primary"
icon=
"el-icon-edit"
size=
"mini"
circle
/>
<el-button
@
click=
"del(scope.row)"
type=
"danger"
icon=
"el-icon-delete"
size=
"mini"
circle
/>
<ms-table-operator
@
editClick=
"edit(scope.row)"
@
deleteClick=
"del(scope.row)"
/>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -48,10 +47,11 @@
import
{
TokenKey
}
from
"
../../../common/js/constants
"
;
import
MsTablePagination
from
"
../common/pagination/TablePagination
"
;
import
MsTableHeader
from
"
../common/components/MsTableHeader
"
;
import
MsTableOperator
from
"
../common/components/MsTableOperator
"
;
export
default
{
name
:
"
MsProject
"
,
components
:
{
MsCreateBox
,
MsTablePagination
,
MsTableHeader
},
components
:
{
Ms
TableOperator
,
Ms
CreateBox
,
MsTablePagination
,
MsTableHeader
},
data
()
{
return
{
createVisible
:
false
,
...
...
frontend/src/business/components/settings/organization/OrganizationWorkspace.vue
浏览文件 @
d0ddd8d8
...
...
@@ -46,19 +46,10 @@
<!-- dialog of workspace member -->
<el-dialog
:visible.sync=
"memberVisible"
width=
"70%"
:destroy-on-close=
"true"
@
close=
"closeMemberFunc"
>
<el-row
type=
"flex"
justify=
"space-between"
align=
"middle"
>
<span
class=
"member-title"
>
{{$t('commons.member')}}
<ms-create-box
:tips=
"addTips"
:exec=
"addMember"
v-permission=
"['admin','org_admin']"
/>
</span>
<span
class=
"search"
>
<el-input
type=
"text"
size=
"small"
:placeholder=
"$t('organization.search_by_name')"
prefix-icon=
"el-icon-search"
maxlength=
"60"
v-model=
"condition.name"
clearable
/>
</span>
</el-row>
<ms-table-header
:condition.sync=
"dialogCondition"
@
create=
"addMember"
:create-tip=
"dialogBtnTips"
:title=
"$t('commons.member')"
/>
<!-- organization member table -->
<el-table
:data=
"memberLineData"
style=
"width: 100%"
>
<el-table
:data=
"memberLineData"
style=
"width: 100%
;margin-top: 5px;
"
>
<el-table-column
prop=
"name"
:label=
"$t('commons.username')"
/>
<el-table-column
prop=
"email"
:label=
"$t('commons.email')"
/>
<el-table-column
prop=
"phone"
:label=
"$t('commons.phone')"
/>
...
...
@@ -394,9 +385,11 @@
result
:
{},
loading
:
false
,
createVisible
:
false
,
btnTips
:
this
.
$t
(
'
workspace.add
'
),
btnTips
:
this
.
$t
(
'
workspace.create
'
),
dialogBtnTips
:
this
.
$t
(
'
member.create
'
),
addTips
:
this
.
$t
(
'
member.create
'
),
condition
:
{},
dialogCondition
:
{},
items
:
[],
currentPage
:
1
,
pageSize
:
5
,
...
...
frontend/src/business/components/settings/system/Organization.vue
浏览文件 @
d0ddd8d8
...
...
@@ -31,19 +31,10 @@
</el-card>
<!-- dialog of organization member -->
<el-dialog
:visible.sync=
"memberVisible"
width=
"70%"
:destroy-on-close=
"true"
@
close=
"closeMemberFunc"
>
<el-row
type=
"flex"
justify=
"space-between"
align=
"middle"
>
<span
class=
"member-title"
>
{{$t('commons.member')}}
<ms-create-box
:tips=
"btnTips"
:exec=
"addMember"
/>
</span>
<span
class=
"search"
>
<el-input
type=
"text"
size=
"small"
:placeholder=
"$t('organization.search_by_name')"
prefix-icon=
"el-icon-search"
maxlength=
"60"
v-model=
"condition.name"
clearable
/>
</span>
</el-row>
<ms-table-header
:condition.sync=
"dialogCondition"
@
create=
"addMember"
:create-tip=
"dialogBtnTips"
:title=
"$t('commons.member')"
/>
<!-- organization member table -->
<el-table
:data=
"memberLineData"
style=
"width: 100%"
>
<el-table
:data=
"memberLineData"
style=
"width: 100%
;margin-top:5px;
"
>
<el-table-column
prop=
"name"
:label=
"$t('commons.username')"
/>
<el-table-column
prop=
"email"
:label=
"$t('commons.email')"
/>
<el-table-column
prop=
"phone"
:label=
"$t('commons.phone')"
/>
...
...
@@ -214,8 +205,10 @@
pageMemberSize
:
5
,
memberTotal
:
0
,
currentRow
:
{},
btnTips
:
this
.
$t
(
'
member.create
'
),
btnTips
:
this
.
$t
(
'
organization.create
'
),
dialogBtnTips
:
this
.
$t
(
'
member.create
'
),
condition
:
{},
dialogCondition
:
{},
tableData
:
[],
memberLineData
:
[],
form
:
{},
...
...
frontend/src/business/components/settings/system/SystemWorkspace.vue
浏览文件 @
d0ddd8d8
...
...
@@ -87,19 +87,10 @@
<!-- dialog of workspace member -->
<el-dialog
:visible.sync=
"memberVisible"
width=
"70%"
:destroy-on-close=
"true"
@
close=
"closeMemberFunc"
>
<el-row
type=
"flex"
justify=
"space-between"
align=
"middle"
>
<span
class=
"member-title"
>
{{$t('commons.member')}}
<ms-create-box
:tips=
"addTips"
:exec=
"addMember"
/>
</span>
<span
class=
"search"
>
<el-input
type=
"text"
size=
"small"
:placeholder=
"$t('organization.search_by_name')"
prefix-icon=
"el-icon-search"
maxlength=
"60"
v-model=
"condition.name"
clearable
/>
</span>
</el-row>
<ms-table-header
:condition.sync=
"dialogCondition"
@
create=
"addMember"
:create-tip=
"dialogBtnTips"
:title=
"$t('commons.member')"
/>
<!-- organization member table -->
<el-table
:data=
"memberLineData"
style=
"width: 100%"
>
<el-table
:data=
"memberLineData"
style=
"width: 100%
;margin-top: 5px;
"
>
<el-table-column
prop=
"name"
:label=
"$t('commons.username')"
/>
<el-table-column
prop=
"email"
:label=
"$t('commons.email')"
/>
<el-table-column
prop=
"phone"
:label=
"$t('commons.phone')"
/>
...
...
@@ -437,9 +428,11 @@
memberVisible
:
false
,
addMemberVisible
:
false
,
updateMemberVisible
:
false
,
btnTips
:
this
.
$t
(
'
workspace.add
'
),
btnTips
:
this
.
$t
(
'
workspace.create
'
),
dialogBtnTips
:
this
.
$t
(
'
member.create
'
),
addTips
:
this
.
$t
(
'
member.create
'
),
condition
:
{},
dialogCondition
:
{},
items
:
[],
currentPage
:
1
,
pageSize
:
5
,
...
...
frontend/src/business/components/settings/workspace/WorkspaceMember.vue
浏览文件 @
d0ddd8d8
...
...
@@ -112,7 +112,7 @@
return
{
result
:
{},
form
:
{},
btnTips
:
"
添加工作空间成员
"
,
btnTips
:
this
.
$t
(
'
member.create
'
)
,
createVisible
:
false
,
updateVisible
:
false
,
queryPath
:
"
/user/ws/member/list
"
,
...
...
frontend/src/business/components/track/case/components/TestCaseList.vue
浏览文件 @
d0ddd8d8
<
template
>
<
template
xmlns:v-slot=
"http://www.w3.org/1999/XSL/Transform"
>
<div>
<el-card
v-loading=
"result.loading"
>
...
...
@@ -27,26 +27,32 @@
</el-table-column>
<el-table-column
prop=
"priority"
:filters=
"priorityFilters"
:filter-method=
"filter"
:label=
"$t('test_track.case.priority')"
show-overflow-tooltip
>
<
template
v-slot:default=
"scope"
>
<priority-table-item
:value=
"scope.row.priority"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"type"
:filters=
"typeFilters"
:filter-method=
"filter"
:label=
"$t('test_track.case.type')"
show-overflow-tooltip
>
<
template
v-slot:default=
"scope"
>
<span
v-if=
"scope.row.type == 'functional'"
>
{{
$t
(
'
test_track.case.functional_test
'
)
}}
</span>
<span
v-if=
"scope.row.type == 'performance'"
>
{{
$t
(
'
commons.performance
'
)
}}
</span>
<span
v-if=
"scope.row.type == 'api'"
>
{{
$t
(
'
commons.api
'
)
}}
</span>
<type-table-item
:value=
"scope.row.type"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"method"
:filters=
"methodFilters"
:filter-method=
"filter"
:label=
"$t('test_track.case.method')"
show-overflow-tooltip
>
<
template
v-slot:default=
"scope"
>
<span
v-if=
"scope.row.method == 'manual'"
>
{{
$t
(
'
test_track.case.manual
'
)
}}
</span>
<span
v-if=
"scope.row.method == 'auto'"
>
{{
$t
(
'
test_track.case.auto
'
)
}}
</span>
<method-table-item
:value=
"scope.row.method"
/>
</
template
>
</el-table-column>
<el-table-column
...
...
@@ -55,12 +61,16 @@
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop=
"createTime"
sortable
:label=
"$t('commons.create_time')"
>
<
template
v-slot:default=
"scope"
>
<span>
{{
scope
.
row
.
createTime
|
timestampFormatDate
}}
</span>
</
template
>
</el-table-column>
<el-table-column
prop=
"updateTime"
sortable
:label=
"$t('commons.update_time')"
>
<
template
v-slot:default=
"scope"
>
<span>
{{
scope
.
row
.
updateTime
|
timestampFormatDate
}}
</span>
...
...
@@ -69,8 +79,7 @@
<el-table-column
:label=
"$t('commons.operating')"
>
<
template
v-slot:default=
"scope"
>
<el-button
@
click=
"handleEdit(scope.row)"
type=
"primary"
icon=
"el-icon-edit"
size=
"mini"
circle
/>
<el-button
@
click=
"handleDelete(scope.row)"
type=
"danger"
icon=
"el-icon-delete"
size=
"mini"
circle
/>
<ms-table-operator
@
editClick=
"handleEdit(scope.row)"
@
deleteClick=
"handleDelete(scope.row)"
/>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -90,20 +99,43 @@
import
MsTablePagination
from
'
../../../../components/common/pagination/TablePagination
'
;
import
NodeBreadcrumb
from
'
../../common/NodeBreadcrumb
'
;
import
MsTableHeader
from
'
../../../../components/common/components/MsTableHeader
'
;
import
PriorityTableItem
from
"
../../common/TableItems/PriorityTableItem
"
;
import
TypeTableItem
from
"
../../common/TableItems/TypeTableItem
"
;
import
MethodTableItem
from
"
../../common/TableItems/MethodTableItem
"
;
import
MsTableOperator
from
"
../../../common/components/MsTableOperator
"
;
export
default
{
name
:
"
TestCaseList
"
,
components
:
{
MsCreateBox
,
TestCaseImport
,
TestCaseExport
,
MsTablePagination
,
NodeBreadcrumb
,
MsTableHeader
},
data
()
{
return
{
result
:
{},
deletePath
:
"
/test/case/delete
"
,
condition
:
{},
tableData
:
[],
currentPage
:
1
,
pageSize
:
5
,
total
:
0
,
}
components
:
{
MsTableOperator
,
MethodTableItem
,
TypeTableItem
,
PriorityTableItem
,
MsCreateBox
,
TestCaseImport
,
TestCaseExport
,
MsTablePagination
,
NodeBreadcrumb
,
MsTableHeader
},
data
()
{
return
{
result
:
{},
deletePath
:
"
/test/case/delete
"
,
condition
:
{},
tableData
:
[],
currentPage
:
1
,
pageSize
:
5
,
total
:
0
,
priorityFilters
:
[
{
text
:
'
P0
'
,
value
:
'
P0
'
},
{
text
:
'
P1
'
,
value
:
'
P1
'
},
{
text
:
'
P2
'
,
value
:
'
P2
'
}
],
methodFilters
:
[
{
text
:
this
.
$t
(
'
test_track.case.manual
'
),
value
:
'
manual
'
},
{
text
:
this
.
$t
(
'
test_track.case.auto
'
),
value
:
'
auto
'
}
],
typeFilters
:
[
{
text
:
this
.
$t
(
'
commons.functional
'
),
value
:
'
functional
'
},
{
text
:
this
.
$t
(
'
commons.performance
'
),
value
:
'
performance
'
},
{
text
:
this
.
$t
(
'
commons.api
'
),
value
:
'
api
'
}
]
}
},
props
:
{
currentProject
:
{
...
...
@@ -174,6 +206,10 @@
refresh
()
{
this
.
condition
=
{};
this
.
$emit
(
'
refresh
'
);
},
filter
(
value
,
row
,
column
)
{
const
property
=
column
[
'
property
'
];
return
row
[
property
]
===
value
;
}
}
}
...
...
frontend/src/business/components/track/common/PlanNodeTree.vue
已删除
100644 → 0
浏览文件 @
cebfba84
<
template
>
<div>
<el-input
:placeholder=
"$t('test_track.module.search')"
v-model=
"filterText"
size=
"small"
></el-input>
<el-tree
v-loading=
"result.loading"
class=
"filter-tree node-tree"
:data=
"treeNodes"
node-key=
"id"
@
node-drag-end=
"handleDragEnd"
:filter-node-method=
"filterNode"
:expand-on-click-node=
"false"
highlight-current
draggable
ref=
"tree"
>
<template
v-slot:default=
"
{node}">
<span
class=
"custom-tree-node"
@
click=
"selectNode(node)"
>
{{
node
.
label
}}
</span>
</
template
>
</el-tree>
</div>
</template>
<
script
>
export
default
{
name
:
"
PlanNodeTree
"
,
data
()
{
return
{
result
:
{},
filterText
:
''
,
defaultProps
:
{
children
:
'
children
'
,
label
:
'
label
'
},
dialogTableVisible
:
false
,
defaultKeys
:
[],
treeNodes
:
[]
};
},
props
:
{
planId
:
{
type
:
String
},
showAll
:
{
type
:
Boolean
}
},
created
()
{
this
.
initTree
();
},
watch
:
{
filterText
(
val
)
{
this
.
$refs
.
tree
.
filter
(
val
);
},
planId
()
{
this
.
initTree
();
},
'
$route
'
(
to
,
from
)
{
if
(
to
.
path
.
indexOf
(
"
/track/plan/view/
"
)
>=
0
){
this
.
initTree
();
}
}
},
selectNode
(
node
)
{
let
nodeIds
=
[];
this
.
getChildNodeId
(
node
,
nodeIds
);
this
.
$emit
(
"
nodeSelectEvent
"
,
nodeIds
);
},
getChildNodeId
(
rootNode
,
nodeIds
)
{
//递归获取所有子节点ID
nodeIds
.
push
(
rootNode
.
data
.
id
);
for
(
let
i
=
0
;
i
<
rootNode
.
childNodes
.
length
;
i
++
)
{
this
.
getChildNodeId
(
rootNode
.
childNodes
[
i
],
nodeIds
);
}
return
nodeIds
;
},
methods
:
{
initTree
()
{
if
(
this
.
showAll
)
{
this
.
getAllNodeTreeByPlanId
();
}
else
{
this
.
getNodeTreeByPlanId
();
}
},
handleDragEnd
(
draggingNode
,
dropNode
,
dropType
,
ev
)
{
let
param
=
{};
param
.
id
=
draggingNode
.
data
.
id
;
if
(
dropType
===
'
inner
'
){
param
.
pId
=
dropNode
.
data
.
id
;
param
.
level
=
dropNode
.
data
.
level
+
1
;
}
else
{
if
(
dropNode
.
parent
.
id
===
0
){
param
.
pId
=
0
;
param
.
level
=
1
;
}
else
{
param
.
pId
=
dropNode
.
parent
.
data
.
id
;
param
.
level
=
dropNode
.
parent
.
data
.
level
+
1
;
}
}
this
.
$post
(
'
/case/node/edit
'
,
param
);
},
selectNode
(
node
)
{
let
nodeIds
=
[];
let
nodeNames
=
[];
this
.
getChildNodeId
(
node
,
nodeIds
);
this
.
getParentNodeName
(
node
,
nodeNames
);
this
.
$emit
(
"
nodeSelectEvent
"
,
nodeIds
,
nodeNames
);
},
getChildNodeId
(
rootNode
,
nodeIds
)
{
//递归获取所有子节点ID
nodeIds
.
push
(
rootNode
.
data
.
id
);
for
(
let
i
=
0
;
i
<
rootNode
.
childNodes
.
length
;
i
++
){
this
.
getChildNodeId
(
rootNode
.
childNodes
[
i
],
nodeIds
);
}
},
getParentNodeName
(
rootNode
,
nodeNames
)
{
if
(
rootNode
.
parent
&&
rootNode
.
parent
.
id
!=
0
)
{
this
.
getParentNodeName
(
rootNode
.
parent
,
nodeNames
)
}
if
(
rootNode
.
data
.
name
&&
rootNode
.
data
.
name
!=
''
)
{
nodeNames
.
push
(
rootNode
.
data
.
name
);
}
},
filterNode
(
value
,
data
)
{
if
(
!
value
)
return
true
;
return
data
.
label
.
indexOf
(
value
)
!==
-
1
;
},
getNodeTreeByPlanId
()
{
if
(
this
.
planId
){
this
.
result
=
this
.
$get
(
"
/case/node/list/plan/
"
+
this
.
planId
,
response
=>
{
this
.
treeNodes
=
response
.
data
;
});
}
},
getAllNodeTreeByPlanId
()
{
if
(
this
.
planId
)
{
this
.
result
=
this
.
$get
(
"
/case/node/list/all/plan/
"
+
this
.
planId
,
response
=>
{
this
.
treeNodes
=
response
.
data
;
});
}
}
}
}
</
script
>
<
style
scoped
>
.el-dropdown-link
{
cursor
:
pointer
;
color
:
#409EFF
;
}
.el-icon-arrow-down
{
font-size
:
12px
;
}
.custom-tree-node
{
flex
:
1
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
font-size
:
14px
;
padding-right
:
8px
;
width
:
100%
;
}
.node-tree
{
margin-top
:
15px
;
}
.father
.child
{
display
:
none
;
}
.father
:hover
.child
{
display
:
block
;
}
</
style
>
frontend/src/business/components/track/common/TableItems/MethodTableItem.vue
0 → 100644
浏览文件 @
d0ddd8d8
<
template
>
<div>
<span
v-if=
"value == 'manual'"
>
{{
$t
(
'
test_track.case.manual
'
)
}}
</span>
<span
v-if=
"value == 'auto'"
>
{{
$t
(
'
test_track.case.auto
'
)
}}
</span>
</div>
</
template
>
<
script
>
export
default
{
name
:
"
MethodTableItem
"
,
props
:
{
value
:
{
type
:
String
}
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/track/common/TableItems/PriorityTableItem.vue
0 → 100644
浏览文件 @
d0ddd8d8
<
template
>
<div>
<el-tag
v-if=
"value == 'P0'"
type=
"danger"
effect=
"dark"
size=
"mini"
>
{{
value
}}
</el-tag>
<el-tag
v-if=
"value == 'P1'"
type=
"danger"
effect=
"light"
size=
"mini"
>
{{
value
}}
</el-tag>
<el-tag
v-if=
"value == 'P2'"
type=
"warning"
effect=
"dark"
size=
"mini"
>
{{
value
}}
</el-tag>
<el-tag
v-if=
"value == 'P3'"
type=
"warning"
effect=
"light"
size=
"mini"
>
{{
value
}}
</el-tag>
</div>
</
template
>
<
script
>
export
default
{
name
:
"
PriorityTableItem
"
,
props
:
{
value
:
{
type
:
String
}
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/track/common/TableItems/StatusTableItem.vue
0 → 100644
浏览文件 @
d0ddd8d8
<
template
>
<div>
<el-tag
v-if=
"value == 'Prepare'"
type=
"info"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan.plan_status_prepare
'
)
}}
</el-tag>
<el-tag
v-if=
"value == 'Pass'"
type=
"success"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.pass
'
)
}}
</el-tag>
<el-tag
v-if=
"value == 'Failure'"
type=
"danger"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.failure
'
)
}}
</el-tag>
<el-tag
v-if=
"value == 'Blocking'"
type=
"warning"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.blocking
'
)
}}
</el-tag>
<el-tag
v-if=
"value == 'Skip'"
type=
"info"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.skip
'
)
}}
</el-tag>
</div>
</
template
>
<
script
>
export
default
{
name
:
"
StatusTableItem
"
,
props
:
{
value
:
{
type
:
String
}
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/track/common/TableItems/TypeTableItem.vue
0 → 100644
浏览文件 @
d0ddd8d8
<
template
>
<div>
<span
v-if=
"value == 'functional'"
>
{{
$t
(
'
commons.functional
'
)
}}
</span>
<span
v-if=
"value == 'performance'"
>
{{
$t
(
'
commons.performance
'
)
}}
</span>
<span
v-if=
"value == 'api'"
>
{{
$t
(
'
commons.api
'
)
}}
</span>
</div>
</
template
>
<
script
>
export
default
{
name
:
"
TypeTableItem
"
,
props
:
{
value
:
{
type
:
String
}
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/track/plan/TestPlan.vue
浏览文件 @
d0ddd8d8
...
...
@@ -43,6 +43,7 @@
this
.
$refs
.
testPlanEditDialog
.
openTestPlanEditDialog
(
data
);
},
refreshTestPlanList
()
{
this
.
$refs
.
testPlanList
.
condition
=
{};
this
.
$refs
.
testPlanList
.
initTableData
();
}
}
...
...
frontend/src/business/components/track/plan/components/TestPlanList.vue
浏览文件 @
d0ddd8d8
...
...
@@ -4,23 +4,8 @@
<el-main
class=
"main-content"
>
<el-card
v-loading=
"result.loading"
>
<template
v-slot:header
>
<div>
<el-row
type=
"flex"
justify=
"space-between"
align=
"middle"
>
<el-col
:span=
"5"
>
<span
class=
"title"
>
{{
$t
(
'
test_track.plan.test_plan
'
)
}}
</span>
<ms-create-box
:tips=
"$t('test_track.plan.create_plan')"
:exec=
"testPlanCreate"
/>
</el-col>
<el-col
:span=
"5"
>
<span
class=
"search"
>
<el-input
type=
"text"
size=
"small"
:placeholder=
"$t('load_test.search_by_name')"
prefix-icon=
"el-icon-search"
maxlength=
"60"
v-model=
"condition"
@
change=
"initTableData"
clearable
/>
</span>
</el-col>
</el-row>
</div>
<ms-table-header
:condition.sync=
"condition"
@
search=
"initTableData"
@
create=
"testPlanCreate"
:create-tip=
"$t('test_track.plan.create_plan')"
:title=
"$t('test_track.plan.test_plan')"
/>
</
template
>
<el-table
...
...
@@ -78,12 +63,7 @@
<el-table-column
:label=
"$t('commons.operating')"
>
<
template
v-slot:default=
"scope"
>
<el-button
@
click=
"handleEdit(scope.row)"
@
click.stop=
"deleteVisible = true"
type=
"primary"
icon=
"el-icon-edit"
size=
"mini"
circle
/>
<el-button
@
click=
"handleDelete(scope.row)"
@
click.stop=
"deleteVisible = true"
type=
"danger"
icon=
"el-icon-delete"
size=
"mini"
circle
/>
<ms-table-operator
@
editClick=
"handleEdit(scope.row)"
@
deleteClick=
"handleDelete(scope.row)"
/>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -99,16 +79,20 @@
<
script
>
import
MsCreateBox
from
'
../../../settings/CreateBox
'
;
import
MsTablePagination
from
'
../../../../components/common/pagination/TablePagination
'
;
import
MsTableHeader
from
"
../../../common/components/MsTableHeader
"
;
import
MsDialogFooter
from
"
../../../common/components/MsDialogFooter
"
;
import
MsTableOperatorButton
from
"
../../../common/components/MsTableOperatorButton
"
;
import
MsTableOperator
from
"
../../../common/components/MsTableOperator
"
;
export
default
{
name
:
"
TestPlanList
"
,
components
:
{
MsCreateBox
,
MsTablePagination
},
components
:
{
Ms
TableOperator
,
MsTableOperatorButton
,
MsDialogFooter
,
MsTableHeader
,
Ms
CreateBox
,
MsTablePagination
},
data
()
{
return
{
result
:
{},
queryPath
:
"
/test/plan/list
"
,
deletePath
:
"
/test/plan/delete
"
,
condition
:
""
,
condition
:
{}
,
currentPage
:
1
,
pageSize
:
5
,
total
:
0
,
...
...
@@ -121,10 +105,7 @@
},
methods
:
{
initTableData
()
{
let
param
=
{
name
:
this
.
condition
,
};
this
.
result
=
this
.
$post
(
this
.
buildPagePath
(
this
.
queryPath
),
param
,
response
=>
{
this
.
result
=
this
.
$post
(
this
.
buildPagePath
(
this
.
queryPath
),
this
.
condition
,
response
=>
{
let
data
=
response
.
data
;
this
.
total
=
data
.
itemCount
;
this
.
tableData
=
data
.
listObject
;
...
...
frontend/src/business/components/track/plan/TestPlanView.vue
→
frontend/src/business/components/track/plan/
view/
TestPlanView.vue
浏览文件 @
d0ddd8d8
...
...
@@ -37,10 +37,10 @@
<
script
>
import
NodeTree
from
"
../common/NodeTree
"
;
import
TestPlanTestCaseList
from
"
./com
p
onents/TestPlanTestCaseList
"
;
import
TestCaseRelevance
from
"
./com
p
onents/TestCaseRelevance
"
;
import
SelectMenu
from
"
../common/SelectMenu
"
;
import
NodeTree
from
"
../
../
common/NodeTree
"
;
import
TestPlanTestCaseList
from
"
./comonents/TestPlanTestCaseList
"
;
import
TestCaseRelevance
from
"
./comonents/TestCaseRelevance
"
;
import
SelectMenu
from
"
../
../
common/SelectMenu
"
;
export
default
{
name
:
"
TestPlanView
"
,
...
...
frontend/src/business/components/track/plan/
comp
onents/ExecutorEdit.vue
→
frontend/src/business/components/track/plan/
view/com
onents/ExecutorEdit.vue
浏览文件 @
d0ddd8d8
...
...
@@ -20,8 +20,8 @@
</template>
<
script
>
import
{
WORKSPACE_ID
}
from
'
../../../../../common/js/constants
'
import
MsDialogFooter
from
'
../../../common/components/MsDialogFooter
'
import
{
WORKSPACE_ID
}
from
'
../../../../../
../
common/js/constants
'
import
MsDialogFooter
from
'
../../../
../
common/components/MsDialogFooter
'
export
default
{
name
:
"
executorEdit
"
,
...
...
frontend/src/business/components/track/plan/
comp
onents/StatusEdit.vue
→
frontend/src/business/components/track/plan/
view/com
onents/StatusEdit.vue
浏览文件 @
d0ddd8d8
...
...
@@ -19,8 +19,8 @@
</template>
<
script
>
import
TestPlanTestCaseStatusButton
from
'
../common/TestPlanTestCaseStatusButton
'
;
import
MsDialogFooter
from
'
../../../common/components/MsDialogFooter
'
import
TestPlanTestCaseStatusButton
from
'
../
../
common/TestPlanTestCaseStatusButton
'
;
import
MsDialogFooter
from
'
../../../
../
common/components/MsDialogFooter
'
export
default
{
name
:
"
statusEdit
"
,
...
...
frontend/src/business/components/track/plan/
comp
onents/TestCaseRelevance.vue
→
frontend/src/business/components/track/plan/
view/com
onents/TestCaseRelevance.vue
浏览文件 @
d0ddd8d8
...
...
@@ -54,8 +54,8 @@
<
script
>
import
NodeTree
from
'
../../common/NodeTree
'
;
import
MsDialogFooter
from
'
../../../common/components/MsDialogFooter
'
import
NodeTree
from
'
../../
../
common/NodeTree
'
;
import
MsDialogFooter
from
'
../../../
../
common/components/MsDialogFooter
'
export
default
{
name
:
"
TestCaseRelevance
"
,
...
...
frontend/src/business/components/track/plan/
comp
onents/TestPlanTestCaseEdit.vue
→
frontend/src/business/components/track/plan/
view/com
onents/TestPlanTestCaseEdit.vue
浏览文件 @
d0ddd8d8
...
...
@@ -165,7 +165,7 @@
</template>
<
script
>
import
TestPlanTestCaseStatusButton
from
'
../common/TestPlanTestCaseStatusButton
'
;
import
TestPlanTestCaseStatusButton
from
'
../
../
common/TestPlanTestCaseStatusButton
'
;
export
default
{
name
:
"
TestPlanTestCaseEdit
"
,
...
...
frontend/src/business/components/track/plan/
comp
onents/TestPlanTestCaseList.vue
→
frontend/src/business/components/track/plan/
view/com
onents/TestPlanTestCaseList.vue
浏览文件 @
d0ddd8d8
...
...
@@ -33,49 +33,36 @@
</el-table-column>
<el-table-column
prop=
"priority"
:filters=
"priorityFilters"
:filter-method=
"filter"
:label=
"$t('test_track.case.priority')"
>
<
template
v-slot:default=
"scope"
>
<el-tag
v-if=
"scope.row.priority == 'P0'"
type=
"danger"
effect=
"dark"
size=
"mini"
>
{{
scope
.
row
.
priority
}}
</el-tag>
<el-tag
v-if=
"scope.row.priority == 'P1'"
type=
"danger"
effect=
"light"
size=
"mini"
>
{{
scope
.
row
.
priority
}}
</el-tag>
<el-tag
v-if=
"scope.row.priority == 'P2'"
type=
"warning"
effect=
"dark"
size=
"mini"
>
{{
scope
.
row
.
priority
}}
</el-tag>
<el-tag
v-if=
"scope.row.priority == 'P3'"
type=
"warning"
effect=
"light"
size=
"mini"
>
{{
scope
.
row
.
priority
}}
</el-tag>
<priority-table-item
:value=
"scope.row.priority"
ref=
"priority"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"type"
:filters=
"typeFilters"
:filter-method=
"filter"
:label=
"$t('test_track.case.type')"
show-overflow-tooltip
>
<
template
v-slot:default=
"scope"
>
<span
v-if=
"scope.row.type == 'functional'"
>
{{
$t
(
'
commons.functional
'
)
}}
</span>
<span
v-if=
"scope.row.type == 'performance'"
>
{{
$t
(
'
commons.performance
'
)
}}
</span>
<span
v-if=
"scope.row.type == 'api'"
>
{{
$t
(
'
commons.api
'
)
}}
</span>
<type-table-item
:value=
"scope.row.type"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"method"
:filters=
"methodFilters"
:filter-method=
"filter"
:label=
"$t('test_track.case.method')"
show-overflow-tooltip
>
<
template
v-slot:default=
"scope"
>
<span
v-if=
"scope.row.method == 'manual'"
>
{{
$t
(
'
test_track.case.manual
'
)
}}
</span>
<span
v-if=
"scope.row.method == 'auto'"
>
{{
$t
(
'
test_track.case.auto
'
)
}}
</span>
<method-table-item
:value=
"scope.row.method"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"executor"
:label=
"$t('test_track.plan_view.executor')"
>
...
...
@@ -83,32 +70,17 @@
<el-table-column
prop=
"status"
:filters=
"statusFilters"
:filter-method=
"filter"
:label=
"$t('test_track.plan_view.execute_result')"
>
<
template
v-slot:default=
"scope"
>
<el-tag
v-if=
"scope.row.status == 'Prepare'"
type=
"info"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan.plan_status_prepare
'
)
}}
</el-tag>
<el-tag
v-if=
"scope.row.status == 'Pass'"
type=
"success"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.pass
'
)
}}
</el-tag>
<el-tag
v-if=
"scope.row.status == 'Failure'"
type=
"danger"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.failure
'
)
}}
</el-tag>
<el-tag
v-if=
"scope.row.status == 'Blocking'"
type=
"warning"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.blocking
'
)
}}
</el-tag>
<el-tag
v-if=
"scope.row.status == 'Skip'"
type=
"info"
effect=
"dark"
size=
"mini"
>
{{
$t
(
'
test_track.plan_view.skip
'
)
}}
</el-tag>
<status-table-item
:value=
"scope.row.status"
/>
</
template
>
</el-table-column>
<el-table-column
sortable
prop=
"updateTime"
:label=
"$t('commons.update_time')"
>
<
template
v-slot:default=
"scope"
>
<span>
{{
scope
.
row
.
updateTime
|
timestampFormatDate
}}
</span>
...
...
@@ -117,8 +89,7 @@
<el-table-column
:label=
"$t('commons.operating')"
>
<
template
v-slot:default=
"scope"
>
<el-button
@
click=
"handleEdit(scope.row, scope.$index)"
type=
"primary"
icon=
"el-icon-edit"
size=
"mini"
circle
/>
<el-button
@
click=
"handleDelete(scope.row)"
type=
"danger"
icon=
"el-icon-unlock"
size=
"mini"
circle
/>
<ms-table-operator
@
editClick=
"handleEdit(scope.row, scope.$index)"
@
deleteClick=
"handleDelete(scope.row)"
/>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -135,21 +106,31 @@
</template>
<
script
>
import
PlanNodeTree
from
'
../../common/PlanNodeTree
'
;
import
ExecutorEdit
from
'
./ExecutorEdit
'
;
import
StatusEdit
from
'
./StatusEdit
'
;
import
TestPlanTestCaseEdit
from
"
.
./components
/TestPlanTestCaseEdit
"
;
import
MsTipButton
from
'
../../../../com
ponents/com
mon/components/MsTipButton
'
;
import
MsTablePagination
from
'
../../../../com
ponents/com
mon/pagination/TablePagination
'
;
import
MsTableHeader
from
'
../../../../com
ponents/com
mon/components/MsTableHeader
'
;
import
MsTableButton
from
'
../../../../com
ponents/com
mon/components/MsTableButton
'
;
import
NodeBreadcrumb
from
'
../../common/NodeBreadcrumb
'
;
import
TestPlanTestCaseEdit
from
"
./TestPlanTestCaseEdit
"
;
import
MsTipButton
from
'
../../../../common/components/MsTipButton
'
;
import
MsTablePagination
from
'
../../../../common/pagination/TablePagination
'
;
import
MsTableHeader
from
'
../../../../common/components/MsTableHeader
'
;
import
MsTableButton
from
'
../../../../common/components/MsTableButton
'
;
import
NodeBreadcrumb
from
'
../../
../
common/NodeBreadcrumb
'
;
import
{
TokenKey
}
from
'
../../../../../common/js/constants
'
;
import
{
TokenKey
}
from
'
../../../../../../common/js/constants
'
;
import
{
tableFilter
}
from
'
../../../../../../common/js/utils
'
;
import
PriorityTableItem
from
"
../../../common/TableItems/PriorityTableItem
"
;
import
StatusTableItem
from
"
../../../common/TableItems/StatusTableItem
"
;
import
TypeTableItem
from
"
../../../common/TableItems/TypeTableItem
"
;
import
MethodTableItem
from
"
../../../common/TableItems/MethodTableItem
"
;
import
MsTableOperator
from
"
../../../../common/components/MsTableOperator
"
;
export
default
{
name
:
"
TestPlanTestCaseList
"
,
components
:
{
PlanNodeTree
,
StatusEdit
,
ExecutorEdit
,
MsTipButton
,
MsTablePagination
,
components
:
{
MsTableOperator
,
MethodTableItem
,
TypeTableItem
,
StatusTableItem
,
PriorityTableItem
,
StatusEdit
,
ExecutorEdit
,
MsTipButton
,
MsTablePagination
,
TestPlanTestCaseEdit
,
MsTableHeader
,
NodeBreadcrumb
,
MsTableButton
},
data
()
{
return
{
...
...
@@ -161,7 +142,28 @@
currentPage
:
1
,
pageSize
:
5
,
total
:
0
,
selectIds
:
new
Set
()
selectIds
:
new
Set
(),
priorityFilters
:
[
{
text
:
'
P0
'
,
value
:
'
P0
'
},
{
text
:
'
P1
'
,
value
:
'
P1
'
},
{
text
:
'
P2
'
,
value
:
'
P2
'
}
],
methodFilters
:
[
{
text
:
this
.
$t
(
'
test_track.case.manual
'
),
value
:
'
manual
'
},
{
text
:
this
.
$t
(
'
test_track.case.auto
'
),
value
:
'
auto
'
}
],
typeFilters
:
[
{
text
:
this
.
$t
(
'
commons.functional
'
),
value
:
'
functional
'
},
{
text
:
this
.
$t
(
'
commons.performance
'
),
value
:
'
performance
'
},
{
text
:
this
.
$t
(
'
commons.api
'
),
value
:
'
api
'
}
],
statusFilters
:
[
{
text
:
this
.
$t
(
'
test_track.plan.plan_status_prepare
'
),
value
:
'
Prepare
'
},
{
text
:
this
.
$t
(
'
test_track.plan_view.pass
'
),
value
:
'
Pass
'
},
{
text
:
this
.
$t
(
'
test_track.plan_view.failure
'
),
value
:
'
Failure
'
},
{
text
:
this
.
$t
(
'
test_track.plan_view.blocking
'
),
value
:
'
Blocking
'
},
{
text
:
this
.
$t
(
'
test_track.plan_view.skip
'
),
value
:
'
Skip
'
},
]
}
},
props
:{
...
...
@@ -267,6 +269,10 @@
this
.
condition
.
executor
=
null
;
}
this
.
initTableData
();
},
filter
(
value
,
row
,
column
)
{
const
property
=
column
[
'
property
'
];
return
row
[
property
]
===
value
;
}
}
}
...
...
frontend/src/i18n/zh-CN.js
浏览文件 @
d0ddd8d8
...
...
@@ -171,6 +171,7 @@ export default {
'
resource_pool_is_null
'
:
'
资源池为空
'
,
},
api_test
:
{
save_and_run
:
"
保存并执行
"
,
input_name
:
"
请输入测试名称
"
,
select_project
:
"
请选择项目
"
,
scenario
:
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录