feat(测试跟踪): 测试用例添加评论

This commit is contained in:
shiziyuan9527 2020-12-17 15:35:16 +08:00
parent ba689c3e27
commit 3f59ca5928
4 changed files with 323 additions and 238 deletions

View File

@ -53,6 +53,7 @@ public class PerformanceTestController {
public Pager<List<LoadTestDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestPlanRequest request) { public Pager<List<LoadTestDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestPlanRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true); Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId()); request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
request.setProjectId(SessionUtils.getCurrentProjectId());
return PageUtils.setPageInfo(page, performanceTestService.list(request)); return PageUtils.setPageInfo(page, performanceTestService.list(request));
} }

View File

@ -79,7 +79,6 @@ public class PerformanceTestService {
public List<LoadTestDTO> list(QueryTestPlanRequest request) { public List<LoadTestDTO> list(QueryTestPlanRequest request) {
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
request.setProjectId(SessionUtils.getCurrentProjectId());
return extLoadTestMapper.list(request); return extLoadTestMapper.list(request);
} }

View File

@ -0,0 +1,66 @@
<template>
<el-card v-loading="result.loading">
<template slot="header">
<span style="font-size: 15px; color: #1E90FF">{{ $t('test_track.review.comment') }}</span>
<i class="el-icon-refresh" @click="getComments()"
style="margin-left:10px;font-size: 14px; cursor: pointer"/>
</template>
<div class="comment-list" style="height: 500px; overflow: auto;">
<review-comment-item v-for="(comment,index) in comments"
:key="index"
:comment="comment"
@refresh="getComments()"/>
<div v-if="comments.length === 0" style="text-align: center">
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
<span style="font-size: 15px; color: #8a8b8d;">
{{ $t('test_track.comment.no_comment') }}
</span>
</i>
</div>
</div>
</el-card>
</template>
<script>
import ReviewCommentItem from "@/business/components/track/review/commom/ReviewCommentItem";
export default {
name: "CaseComment",
components: {ReviewCommentItem},
props: {
caseId: {
type: String,
default: ''
}
},
watch: {
caseId() {
this.comments = [];
this.getComments();
}
},
created() {
this.comments = [];
this.getComments();
},
data() {
return {
comments: [],
result: {}
}
},
methods: {
getComments() {
if (this.caseId) {
this.result = this.$get('/test/case/comment/list/' + this.caseId, res => {
this.comments = res.data;
})
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,255 +1,263 @@
<template> <template>
<div> <el-dialog :close-on-click-modal="false" class="case-dialog"
@close="close"
:title="operationType == 'edit' ? ( readOnly ? $t('test_track.case.view_case') : $t('test_track.case.edit_case')) : $t('test_track.case.create')"
:visible.sync="dialogFormVisible" width="88%">
<el-dialog :close-on-click-modal="false" <el-row :gutter="10">
@close="close" <div>
:title="operationType == 'edit' ? ( readOnly ? $t('test_track.case.view_case') : $t('test_track.case.edit_case')) : $t('test_track.case.create')" <el-col :span="17">
:visible.sync="dialogFormVisible" width="65%"> <el-card>
<el-form :model="form" :rules="rules" ref="caseFrom" v-loading="result.loading">
<el-form :model="form" :rules="rules" ref="caseFrom" v-loading="result.loading"> <el-row>
<el-col :span="8" :offset="1">
<el-form-item
:placeholder="$t('test_track.case.input_name')"
:label="$t('test_track.case.name')"
:label-width="formLabelWidth"
prop="name">
<el-input class="case-name" :disabled="readOnly" v-model="form.name"></el-input>
</el-form-item>
</el-col>
<el-row> <el-col :span="11" :offset="2">
<el-col :span="8" :offset="1"> <el-form-item :label="$t('test_track.case.module')" :label-width="formLabelWidth" prop="module">
<el-form-item <el-select
:placeholder="$t('test_track.case.input_name')" v-model="form.module"
:label="$t('test_track.case.name')" :disabled="readOnly"
:label-width="formLabelWidth" :placeholder="$t('test_track.case.input_module')"
prop="name"> filterable>
<el-input class="case-name" :disabled="readOnly" v-model="form.name"></el-input> <el-option
</el-form-item> v-for="item in moduleOptions"
</el-col> :key="item.id"
:label="item.path"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-col :span="11" :offset="2"> <el-row>
<el-form-item :label="$t('test_track.case.module')" :label-width="formLabelWidth" prop="module"> <el-col :span="10" :offset="1">
<el-select <el-form-item :label="$t('test_track.case.maintainer')" :label-width="formLabelWidth" prop="maintainer">
v-model="form.module" <el-select :disabled="readOnly" v-model="form.maintainer"
:disabled="readOnly" :placeholder="$t('test_track.case.input_maintainer')" filterable>
:placeholder="$t('test_track.case.input_module')" <el-option
filterable> v-for="item in maintainerOptions"
<el-option :key="item.id"
v-for="item in moduleOptions" :label="item.id + ' (' + item.name + ')'"
:key="item.id" :value="item.id">
:label="item.path" </el-option>
:value="item.id"> </el-select>
</el-option> </el-form-item>
</el-select> </el-col>
</el-form-item> <el-col :span="12">
</el-col> <el-form-item :label="$t('test_track.case.priority')" :label-width="formLabelWidth" prop="priority">
</el-row> <el-select :disabled="readOnly" v-model="form.priority" clearable
:placeholder="$t('test_track.case.input_priority')">
<el-option label="P0" value="P0"></el-option>
<el-option label="P1" value="P1"></el-option>
<el-option label="P2" value="P2"></el-option>
<el-option label="P3" value="P3"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row> <el-row>
<el-col :span="10" :offset="1"> <el-col :span="10" :offset="1">
<el-form-item :label="$t('test_track.case.maintainer')" :label-width="formLabelWidth" prop="maintainer"> <el-form-item :label="$t('test_track.case.type')" :label-width="formLabelWidth" prop="type">
<el-select :disabled="readOnly" v-model="form.maintainer" <el-select @change="typeChange" :disabled="readOnly" v-model="form.type"
:placeholder="$t('test_track.case.input_maintainer')" filterable> :placeholder="$t('test_track.case.input_type')">
<el-option <el-option :label="$t('commons.functional')" value="functional"></el-option>
v-for="item in maintainerOptions" <el-option :label="$t('commons.performance')" value="performance"></el-option>
:key="item.id" <el-option :label="$t('commons.api')" value="api"></el-option>
:label="item.id + ' (' + item.name + ')'" </el-select>
:value="item.id"> </el-form-item>
</el-option> </el-col>
</el-select> <el-col :span="12">
</el-form-item> <el-form-item :label="$t('test_track.case.method')" :label-width="formLabelWidth" prop="method">
</el-col> <el-select :disabled="readOnly" v-model="form.method" :placeholder="$t('test_track.case.input_method')">
<el-col :span="12"> <el-option
<el-form-item :label="$t('test_track.case.priority')" :label-width="formLabelWidth" prop="priority"> v-for="item in methodOptions"
<el-select :disabled="readOnly" v-model="form.priority" clearable :key="item.value"
:placeholder="$t('test_track.case.input_priority')"> :label="item.label"
<el-option label="P0" value="P0"></el-option> :value="item.value">
<el-option label="P1" value="P1"></el-option> </el-option>
<el-option label="P2" value="P2"></el-option> </el-select>
<el-option label="P3" value="P3"></el-option> </el-form-item>
</el-select> </el-col>
</el-form-item> </el-row>
</el-col>
</el-row>
<el-row> <el-row v-if="form.method && form.method == 'auto'">
<el-col :span="10" :offset="1"> <el-col :span="9" :offset="1">
<el-form-item :label="$t('test_track.case.type')" :label-width="formLabelWidth" prop="type"> <el-form-item :label="$t('test_track.case.relate_test')" :label-width="formLabelWidth" prop="testId">
<el-select @change="typeChange" :disabled="readOnly" v-model="form.type" <el-select filterable :disabled="readOnly" v-model="form.testId"
:placeholder="$t('test_track.case.input_type')"> :placeholder="$t('test_track.case.input_type')">
<el-option :label="$t('commons.functional')" value="functional"></el-option> <el-option
<el-option :label="$t('commons.performance')" value="performance"></el-option> v-for="item in testOptions"
<el-option :label="$t('commons.api')" value="api"></el-option> :key="item.id"
</el-select> :label="item.name"
</el-form-item> :value="item.id">
</el-col> </el-option>
<el-col :span="12"> </el-select>
<el-form-item :label="$t('test_track.case.method')" :label-width="formLabelWidth" prop="method"> </el-form-item>
<el-select :disabled="readOnly" v-model="form.method" :placeholder="$t('test_track.case.input_method')"> </el-col>
<el-option <el-col :span="9" :offset="1" v-if="form.testId=='other'">
v-for="item in methodOptions" <el-form-item :label="$t('test_track.case.test_name')" :label-width="formLabelWidth" prop="testId">
:key="item.value" <el-input v-model="form.otherTestName" :placeholder="$t('test_track.case.input_test_case')"></el-input>
:label="item.label" </el-form-item>
:value="item.value"> </el-col>
</el-option> </el-row>
</el-select> <el-row style="margin-top: 15px;">
</el-form-item> <el-col :offset="2">{{ $t('test_track.case.prerequisite') }}:</el-col>
</el-col> </el-row>
</el-row> <el-row type="flex" justify="center" style="margin-top: 10px;">
<el-col :span="20">
<el-form-item prop="prerequisite">
<el-input :disabled="readOnly" v-model="form.prerequisite"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:rows="2"
:placeholder="$t('test_track.case.input_prerequisite')"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="form.method && form.method == 'auto'"> <el-row v-if="form.method && form.method != 'auto'" style="margin-bottom: 10px">
<el-col :span="9" :offset="1"> <el-col :offset="2">{{ $t('test_track.case.steps') }}:</el-col>
<el-form-item :label="$t('test_track.case.relate_test')" :label-width="formLabelWidth" prop="testId"> </el-row>
<el-select filterable :disabled="readOnly" v-model="form.testId"
:placeholder="$t('test_track.case.input_type')">
<el-option
v-for="item in testOptions"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="9" :offset="1" v-if="form.testId=='other'">
<el-form-item :label="$t('test_track.case.test_name')" :label-width="formLabelWidth" prop="testId">
<el-input v-model="form.otherTestName" :placeholder="$t('test_track.case.input_test_case')"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row style="margin-top: 15px;">
<el-col :offset="2">{{ $t('test_track.case.prerequisite') }}:</el-col>
</el-row>
<el-row type="flex" justify="center" style="margin-top: 10px;">
<el-col :span="20">
<el-form-item prop="prerequisite">
<el-input :disabled="readOnly" v-model="form.prerequisite"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:rows="2"
:placeholder="$t('test_track.case.input_prerequisite')"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="form.method && form.method != 'auto'" style="margin-bottom: 10px"> <el-row v-if="form.method && form.method != 'auto'" type="flex" justify="center">
<el-col :offset="2">{{ $t('test_track.case.steps') }}:</el-col> <el-col :span="20">
</el-row> <el-table
v-if="isStepTableAlive"
<el-row v-if="form.method && form.method != 'auto'" type="flex" justify="center"> :data="form.steps"
<el-col :span="20"> class="tb-edit"
<el-table border
v-if="isStepTableAlive"
:data="form.steps"
class="tb-edit"
border
size="mini"
:default-sort="{prop: 'num', order: 'ascending'}"
highlight-current-row>
<el-table-column :label="$t('test_track.case.number')" prop="num" min-width="10%"></el-table-column>
<el-table-column :label="$t('test_track.case.step_desc')" prop="desc" min-width="35%">
<template v-slot:default="scope">
<el-input
class="table-edit-input"
size="mini" size="mini"
:disabled="readOnly" :default-sort="{prop: 'num', order: 'ascending'}"
type="textarea" highlight-current-row>
:autosize="{ minRows: 1, maxRows: 6}" <el-table-column :label="$t('test_track.case.number')" prop="num" min-width="10%"></el-table-column>
:rows="2" <el-table-column :label="$t('test_track.case.step_desc')" prop="desc" min-width="35%">
v-model="scope.row.desc" <template v-slot:default="scope">
:placeholder="$t('commons.input_content')" <el-input
clearable/> class="table-edit-input"
</template> size="mini"
</el-table-column> :disabled="readOnly"
<el-table-column :label="$t('test_track.case.expected_results')" prop="result" min-width="35%"> type="textarea"
<template v-slot:default="scope"> :autosize="{ minRows: 1, maxRows: 6}"
<el-input :rows="2"
class="table-edit-input" v-model="scope.row.desc"
size="mini" :placeholder="$t('commons.input_content')"
:disabled="readOnly" clearable/>
type="textarea" </template>
:autosize="{ minRows: 1, maxRows: 6}" </el-table-column>
:rows="2" <el-table-column :label="$t('test_track.case.expected_results')" prop="result" min-width="35%">
v-model="scope.row.result" <template v-slot:default="scope">
:placeholder="$t('commons.input_content')" <el-input
clearable/> class="table-edit-input"
</template> size="mini"
</el-table-column> :disabled="readOnly"
<el-table-column :label="$t('commons.input_content')" min-width="20%"> type="textarea"
<template v-slot:default="scope"> :autosize="{ minRows: 1, maxRows: 6}"
<el-button :rows="2"
type="primary" v-model="scope.row.result"
:disabled="readOnly" :placeholder="$t('commons.input_content')"
icon="el-icon-plus" clearable/>
circle size="mini" </template>
@click="handleAddStep(scope.$index, scope.row)"></el-button> </el-table-column>
<el-button <el-table-column :label="$t('commons.input_content')" min-width="20%">
icon="el-icon-document-copy" <template v-slot:default="scope">
type="success" <el-button
:disabled="readOnly" type="primary"
circle size="mini" :disabled="readOnly"
@click="handleCopyStep(scope.$index, scope.row)"></el-button> icon="el-icon-plus"
<el-button circle size="mini"
type="danger" @click="handleAddStep(scope.$index, scope.row)"></el-button>
icon="el-icon-delete" <el-button
circle size="mini" icon="el-icon-document-copy"
@click="handleDeleteStep(scope.$index, scope.row)" type="success"
:disabled="readOnly || (scope.$index == 0 && form.steps.length <= 1)"></el-button> :disabled="readOnly"
</template> circle size="mini"
</el-table-column> @click="handleCopyStep(scope.$index, scope.row)"></el-button>
</el-table> <el-button
</el-col> type="danger"
</el-row> icon="el-icon-delete"
circle size="mini"
@click="handleDeleteStep(scope.$index, scope.row)"
:disabled="readOnly || (scope.$index == 0 && form.steps.length <= 1)"></el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<el-row style="margin-top: 15px;margin-bottom: 10px"> <el-row style="margin-top: 15px;margin-bottom: 10px">
<el-col :offset="2">{{ $t('commons.remark') }}:</el-col> <el-col :offset="2">{{ $t('commons.remark') }}:</el-col>
</el-row> </el-row>
<el-row type="flex" justify="center"> <el-row type="flex" justify="center">
<el-col :span="20"> <el-col :span="20">
<el-form-item prop="remark"> <el-form-item prop="remark">
<el-input v-model="form.remark" <el-input v-model="form.remark"
:autosize="{ minRows: 2, maxRows: 4}" :autosize="{ minRows: 2, maxRows: 4}"
type="textarea" type="textarea"
:disabled="readOnly" :disabled="readOnly"
:rows="2" :rows="2"
:placeholder="$t('commons.input_content')"></el-input> :placeholder="$t('commons.input_content')"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row style="margin-top: 15px;margin-bottom: 10px"> <el-row style="margin-top: 15px;margin-bottom: 10px">
<el-col :offset="2" :span="20">{{ $t('test_track.case.attachment') }}: <el-col :offset="2" :span="20">{{ $t('test_track.case.attachment') }}:
<el-upload <el-upload
accept=".jpg,.jpeg,.png,.xlsx,.doc,.pdf,.docx" accept=".jpg,.jpeg,.png,.xlsx,.doc,.pdf,.docx"
action="" action=""
:show-file-list="false" :show-file-list="false"
:before-upload="beforeUpload" :before-upload="beforeUpload"
:http-request="handleUpload" :http-request="handleUpload"
:on-exceed="handleExceed" :on-exceed="handleExceed"
multiple multiple
:limit="8" :limit="8"
:file-list="fileList"> :file-list="fileList">
<el-button icon="el-icon-plus" size="mini"></el-button> <el-button icon="el-icon-plus" size="mini"></el-button>
<span slot="tip" class="el-upload__tip"> {{ $t('test_track.case.upload_tip') }} </span> <span slot="tip" class="el-upload__tip"> {{ $t('test_track.case.upload_tip') }} </span>
</el-upload> </el-upload>
</el-col> </el-col>
<el-col :offset="2" :span="20"> <el-col :offset="2" :span="20">
<test-case-attachment :table-data="tableData" <test-case-attachment :table-data="tableData"
:read-only="readOnly" :read-only="readOnly"
:is-delete="true" :is-delete="true"
@handleDelete="handleDelete" @handleDelete="handleDelete"
/> />
</el-col> </el-col>
</el-row> </el-row>
</el-form> <el-row style="float: right; margin-bottom: 10px;">
<el-switch v-if="operationType == 'add'"
v-model="isCreateContinue"
:active-text="$t('test_track.case.save_create_continue')">
</el-switch>
<ms-dialog-footer v-if="!readOnly"
@cancel="dialogFormVisible = false"
@confirm="saveCase"/>
</el-row>
<template v-slot:footer> </el-form>
<el-switch v-if="operationType == 'add'"
v-model="isCreateContinue"
:active-text="$t('test_track.case.save_create_continue')">
</el-switch>
<ms-dialog-footer v-if="!readOnly"
@cancel="dialogFormVisible = false"
@confirm="saveCase"/>
</template>
</el-dialog> </el-card>
</el-col>
<el-col :span="7">
<case-comment :case-id="testCase ? testCase.id : ''"/>
</el-col>
</div>
</el-row>
</div> </el-dialog>
</template> </template>
@ -264,10 +272,11 @@ import {Message} from "element-ui";
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment"; import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
import {getCurrentProjectID} from "../../../../../common/js/utils"; import {getCurrentProjectID} from "../../../../../common/js/utils";
import {buildNodePath} from "../../../api/definition/model/NodeTree"; import {buildNodePath} from "../../../api/definition/model/NodeTree";
import CaseComment from "@/business/components/track/case/components/CaseComment";
export default { export default {
name: "TestCaseEdit", name: "TestCaseEdit",
components: {MsDialogFooter, TestCaseAttachment}, components: {CaseComment, MsDialogFooter, TestCaseAttachment},
data() { data() {
return { return {
result: {}, result: {},
@ -318,7 +327,8 @@ export default {
methodOptions: [ methodOptions: [
{value: 'auto', label: this.$t('test_track.case.auto')}, {value: 'auto', label: this.$t('test_track.case.auto')},
{value: 'manual', label: this.$t('test_track.case.manual')} {value: 'manual', label: this.$t('test_track.case.manual')}
] ],
testCase: {}
}; };
}, },
props: { props: {
@ -347,6 +357,11 @@ export default {
this.$nextTick(() => (this.isStepTableAlive = true)); this.$nextTick(() => (this.isStepTableAlive = true));
}, },
open(testCase) { open(testCase) {
this.testCase = {};
if (testCase) {
//
this.testCase = testCase.isCopy ? {} : testCase;
}
this.resetForm(); this.resetForm();
this.projectId = getCurrentProjectID(); this.projectId = getCurrentProjectID();
if (window.history && window.history.pushState) { if (window.history && window.history.pushState) {
@ -697,4 +712,8 @@ export default {
width: 194px; width: 194px;
} }
.case-dialog >>> .el-dialog__body {
padding: 0 20px 10px 20px;
}
</style> </style>