fix(测试跟踪): 修复功能用例执行时翻页偶尔不显示下一条用例的缺陷

--bug=1010551 --user=宋天阳 测试计划-功能用例执行用例时,翻页时不显示下一页用例名称
https://www.tapd.cn/55049933/s/1109274
This commit is contained in:
song-tianyang 2022-02-23 18:45:11 +08:00 committed by 刘瑞斌
parent 7fbbb7a505
commit 0d4d63a171
7 changed files with 169 additions and 98 deletions

View File

@ -19,6 +19,8 @@ public interface ExtTestPlanTestCaseMapper {
List<TestPlanCaseDTO> list(@Param("request") QueryTestPlanCaseRequest request); List<TestPlanCaseDTO> list(@Param("request") QueryTestPlanCaseRequest request);
List<String> nameList(@Param("request") QueryTestPlanCaseRequest request);
List<TestPlanCaseDTO> listByPlanId(@Param("request") QueryTestPlanCaseRequest request); List<TestPlanCaseDTO> listByPlanId(@Param("request") QueryTestPlanCaseRequest request);
List<TestPlanCaseDTO> listByNode(@Param("request") QueryTestPlanCaseRequest request); List<TestPlanCaseDTO> listByNode(@Param("request") QueryTestPlanCaseRequest request);
@ -37,6 +39,7 @@ public interface ExtTestPlanTestCaseMapper {
/** /**
* 根据项目 ids 查询 TestPlanCaseDTO 列表 * 根据项目 ids 查询 TestPlanCaseDTO 列表
*
* @param ids project id list * @param ids project id list
* @return List<TestPlanCaseDTO> * @return List<TestPlanCaseDTO>
*/ */
@ -66,9 +69,9 @@ public interface ExtTestPlanTestCaseMapper {
List<String> getIdsOrderByUpdateTime(@Param("planId") String planId); List<String> getIdsOrderByUpdateTime(@Param("planId") String planId);
Long getPreOrder(@Param("planId")String planId, @Param("baseOrder") Long baseOrder); Long getPreOrder(@Param("planId") String planId, @Param("baseOrder") Long baseOrder);
Long getLastOrder(@Param("planId")String planId, @Param("baseOrder") Long baseOrder); Long getLastOrder(@Param("planId") String planId, @Param("baseOrder") Long baseOrder);
List<TestCase> getTestCaseWithNodeInfo(@Param("planId") String planId); List<TestCase> getTestCaseWithNodeInfo(@Param("planId") String planId);
} }

View File

@ -267,6 +267,34 @@
</foreach> </foreach>
</if> </if>
</select> </select>
<select id="nameList" resultType="java.lang.String">
select test_case.name
from test_plan_test_case
inner join test_case on test_plan_test_case.case_id = test_case.id
left join test_case_node on test_case_node.id = test_case.node_id
inner join project on project.id = test_case.project_id
left join project_version on project_version.id = test_case.version_id and project.id =
project_version.project_id
<include refid="queryWhereCondition"/>
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
<choose>
<when test="order.name == 'custom_num'">
customNum ${order.type}
</when>
<when test="order.name == 'name'">
test_case.name ${order.type}
</when>
<otherwise>
test_plan_test_case.${order.name} ${order.type}
</otherwise>
</choose>
</foreach>
</if>
</select>
<select id="selectIds" resultType="java.lang.String"> <select id="selectIds" resultType="java.lang.String">
select distinct test_plan_test_case.id as id select distinct test_plan_test_case.id as id
from test_plan_test_case from test_plan_test_case

View File

@ -33,6 +33,11 @@ public class TestPlanTestCaseController {
return PageUtils.setPageInfo(page, testPlanTestCaseService.list(request)); return PageUtils.setPageInfo(page, testPlanTestCaseService.list(request));
} }
@PostMapping("/nameList")
public List<String> getTestPlanCaseNames(@RequestBody QueryTestPlanCaseRequest request) {
return testPlanTestCaseService.getTestPlanCaseNames(request);
}
/*jenkins测试计划下全部用例*/ /*jenkins测试计划下全部用例*/
@GetMapping("/list/{planId}") @GetMapping("/list/{planId}")
public List<TestPlanCaseDTO> getTestPlanCaseByPlanId(@PathVariable String planId) { public List<TestPlanCaseDTO> getTestPlanCaseByPlanId(@PathVariable String planId) {

View File

@ -434,4 +434,10 @@ public class TestPlanTestCaseService {
extTestPlanTestCaseMapper::getLastOrder, extTestPlanTestCaseMapper::getLastOrder,
testPlanTestCaseMapper::updateByPrimaryKeySelective); testPlanTestCaseMapper::updateByPrimaryKeySelective);
} }
public List<String> getTestPlanCaseNames(QueryTestPlanCaseRequest request) {
request.setOrders(ServiceUtils.getDefaultSortOrder(request.getOrders()));
List<String> list = extTestPlanTestCaseMapper.nameList(request);
return list;
}
} }

View File

@ -1,86 +1,92 @@
<template> <template>
<span class="previous-next-button"> <span class="previous-next-button">
<span class="head-right-tip" v-if="countNum === total"> <span class="head-right-tip" v-if="countNum === total">
{{ $t('test_track.plan_view.pre_case') }} : {{list[index - 1] ? list[index - 1].name : ''}} {{ $t('test_track.plan_view.pre_case') }} : {{ testCaseNameArr[countNum - 1] ? testCaseNameArr[countNum - 1] : '' }}
</span> </span>
<span class="head-right-tip" v-if="countNum !== total"> <span class="head-right-tip" v-if="countNum !== total">
{{ $t('test_track.plan_view.next_case') }} : {{list[index + 1] ? list[index + 1].name : ''}} {{ $t('test_track.plan_view.next_case') }} : {{ testCaseNameArr[countNum] ? testCaseNameArr[countNum] : '' }}
</span> </span>
<el-button plain size="mini" icon="el-icon-arrow-up" :disabled="countNum <= 1" @click="handlePre()"/> <el-button plain size="mini" icon="el-icon-arrow-up" :disabled="countNum <= 1" @click="handlePre()"/>
<span> <span>
{{ countNum }}/{{ total }} {{ countNum }}/{{ total }}
</span> </span>
<el-button plain size="mini" icon="el-icon-arrow-down" :disabled="countNum >= total" @click="handleNext()"/> <el-button plain size="mini" icon="el-icon-arrow-down" :disabled="(countNum+1) >= total" @click="handleNext()"/>
</span> </span>
</template> </template>
<script> <script>
export default { export default {
name: "MsPreviousNextButton", name: "MsPreviousNextButton",
data() { data() {
return { return {
countNum: 1 countNum: 1
} }
}, },
props: { props: {
list: { list: {
type: Array, type: Array,
default() { default() {
return [] return []
} }
}, },
index: { index: {
type: Number, type: Number,
default() { default() {
return 0 return 0
} }
}, },
pageTotal: { pageTotal: {
type: Number, type: Number,
default() { default() {
return 0 return 0
} }
}, },
total: { total: {
type: Number, type: Number,
default() { default() {
return 0 return 0
} }
}, },
pageNum: { pageNum: {
type: Number, type: Number,
default() { default() {
return 0 return 0
} }
}, },
pageSize: { testCaseNameArr: {
type: Number, type: Array
default() { },
return 0 pageSize: {
} type: Number,
} default() {
}, return 0
watch: {
index() {
this.countNum = this.pageSize * (this.pageNum - 1) + this.index + 1;
}
},
methods: {
handlePre() {
this.$emit('pre');
},
handleNext() {
this.$emit('next');
}
} }
} }
},
watch: {
index() {
this.countNum = this.pageSize * (this.pageNum - 1) + this.index + 1;
}
},
mounted() {
this.countNum = this.pageSize * (this.pageNum - 1) + this.index + 1;
},
methods: {
handlePre() {
this.$emit('pre');
},
handleNext() {
this.$emit('next');
}
}
}
</script> </script>
<style scoped> <style scoped>
.head-right-tip { .head-right-tip {
color: darkgrey; color: darkgrey;
} }
</style> </style>

View File

@ -32,12 +32,14 @@
:page-num="pageNum" :page-num="pageNum"
:page-size="pageSize" :page-size="pageSize"
:page-total="pageTotal" :page-total="pageTotal"
:test-case-name-arr="testCaseNames"
:total="total" :total="total"
@pre="handlePre" @pre="handlePre"
@next="saveCase(true, true)" @next="saveCase(true, true)"
:list="testCases"/> :list="testCases"/>
<el-button class="save-btn" type="primary" size="mini" :disabled="isReadOnly" @click="saveCase(true)"> <el-button class="save-btn" type="primary" size="mini" :disabled="isReadOnly"
{{$t('test_track.save')}} & {{$t('test_track.next')}} @click="saveCase(true)">
{{ $t('test_track.save') }} & {{ $t('test_track.next') }}
</el-button> </el-button>
</el-col> </el-col>
@ -46,7 +48,9 @@
<el-row class="head-bar"> <el-row class="head-bar">
<el-col> <el-col>
<el-divider content-position="left"> <el-divider content-position="left">
<el-button class="test-case-name" type="text" @click="openTestTestCase(testCase)">{{ testCase.name }}</el-button> <el-button class="test-case-name" type="text" @click="openTestTestCase(testCase)">
{{ testCase.name }}
</el-button>
</el-divider> </el-divider>
</el-col> </el-col>
</el-row> </el-row>
@ -58,14 +62,16 @@
<el-row> <el-row>
<el-col :span="7"> <el-col :span="7">
<el-form-item :label="$t('test_track.case.module')" prop="nodePath" :label-width="formLabelWidth"> <el-form-item :label="$t('test_track.case.module')" prop="nodePath"
{{testCase.nodePath}} :label-width="formLabelWidth">
</el-form-item > {{ testCase.nodePath }}
</el-form-item>
</el-col> </el-col>
<el-col :span="7"> <el-col :span="7">
<el-form-item :label="$t('test_track.plan.plan_project')" prop="projectName" :label-width="formLabelWidth"> <el-form-item :label="$t('test_track.plan.plan_project')" prop="projectName"
{{testCase.projectName}} :label-width="formLabelWidth">
</el-form-item > {{ testCase.projectName }}
</el-form-item>
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
<test-plan-test-case-status-button class="status-button" <test-plan-test-case-status-button class="status-button"
@ -110,7 +116,7 @@
<test-case-edit-other-info :plan-id="testCase.planId" v-if="otherInfoActive" @openTest="openTest" <test-case-edit-other-info :plan-id="testCase.planId" v-if="otherInfoActive" @openTest="openTest"
:read-only="true" :is-test-plan="true" :project-id="testCase.projectId" :read-only="true" :is-test-plan="true" :project-id="testCase.projectId"
:form="testCase" :case-id="testCase.caseId" ref="otherInfo"/> :form="testCase" :case-id="testCase.caseId" ref="otherInfo"/>
</el-form-item > </el-form-item>
</el-form> </el-form>
</div> </div>
@ -164,7 +170,8 @@ import {SYSTEM_FIELD_NAME_MAP} from "@/common/js/table-constants";
import IssueDescriptionTableItem from "@/business/components/track/issue/IssueDescriptionTableItem"; import IssueDescriptionTableItem from "@/business/components/track/issue/IssueDescriptionTableItem";
import StepChangeItem from "@/business/components/track/case/components/StepChangeItem"; import StepChangeItem from "@/business/components/track/case/components/StepChangeItem";
import TestCaseStepItem from "@/business/components/track/case/components/TestCaseStepItem"; import TestCaseStepItem from "@/business/components/track/case/components/TestCaseStepItem";
import TestPlanCaseStepResultsItem from "@/business/components/track/plan/view/comonents/functional/TestPlanCaseStepResultsItem"; import TestPlanCaseStepResultsItem
from "@/business/components/track/plan/view/comonents/functional/TestPlanCaseStepResultsItem";
export default { export default {
name: "FunctionalTestCaseEdit", name: "FunctionalTestCaseEdit",
@ -224,6 +231,9 @@ export default {
searchParam: { searchParam: {
type: Object type: Object
}, },
testCaseNames: {
type: Array
},
pageNum: Number, pageNum: Number,
pageSize: { pageSize: {
type: Number, type: Number,
@ -482,7 +492,10 @@ export default {
break; break;
} }
case "testcase": { case "testcase": {
let caseData = this.$router.resolve({name:'ApiDefinition',params:{redirectID:getUUID(),dataType:"apiTestCase",dataSelectRange:'single:'+id}}); let caseData = this.$router.resolve({
name: 'ApiDefinition',
params: {redirectID: getUUID(), dataType: "apiTestCase", dataSelectRange: 'single:' + id}
});
window.open(caseData.href, '_blank'); window.open(caseData.href, '_blank');
break; break;
} }

View File

@ -84,11 +84,11 @@
</ms-table-column> </ms-table-column>
<ms-table-column <ms-table-column
prop="tags" prop="tags"
:field="item" :field="item"
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
:label="$t('commons.tag')" :label="$t('commons.tag')"
min-width="120px"> min-width="120px">
<template v-slot:default="scope"> <template v-slot:default="scope">
<ms-tag v-for="(tag, index) in scope.row.showTags" :key="tag + '_' + index" type="success" effect="plain" <ms-tag v-for="(tag, index) in scope.row.showTags" :key="tag + '_' + index" type="success" effect="plain"
:content="tag" style="margin-left: 0px; margin-right: 2px"/> :content="tag" style="margin-left: 0px; margin-right: 2px"/>
@ -96,26 +96,26 @@
</template> </template>
</ms-table-column> </ms-table-column>
<ms-table-column <ms-table-column
sortable sortable
prop="createTime" prop="createTime"
:field="item" :field="item"
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
:label="$t('commons.create_time')" :label="$t('commons.create_time')"
min-width="140px"> min-width="140px">
<template v-slot:default="scope"> <template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span> <span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template> </template>
</ms-table-column> </ms-table-column>
<ms-table-column <ms-table-column
prop="nodePath" prop="nodePath"
:field="item" :field="item"
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
:label="$t('test_track.case.module')" :label="$t('test_track.case.module')"
min-width="120px"/> min-width="120px"/>
<ms-table-column <ms-table-column
prop="projectName" prop="projectName"
:field="item" :field="item"
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
:label="$t('test_track.plan.plan_project')" :label="$t('test_track.plan.plan_project')"
@ -162,7 +162,7 @@
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
:label="$t('test_track.plan_view.executor')"> :label="$t('test_track.plan_view.executor')">
<template v-slot:default="scope"> <template v-slot:default="scope">
{{scope.row.executorName}} {{ scope.row.executorName }}
</template> </template>
</ms-table-column> </ms-table-column>
@ -231,10 +231,11 @@
:prop="field.name"> :prop="field.name">
<template v-slot="scope"> <template v-slot="scope">
<span v-if="field.name === '用例等级'"> <span v-if="field.name === '用例等级'">
<priority-table-item :value="getCustomFieldValue(scope.row, field) ? getCustomFieldValue(scope.row, field) : scope.row.priority"/> <priority-table-item
:value="getCustomFieldValue(scope.row, field) ? getCustomFieldValue(scope.row, field) : scope.row.priority"/>
</span> </span>
<span v-else> <span v-else>
{{getCustomFieldValue(scope.row, field)}} {{ getCustomFieldValue(scope.row, field) }}
</span> </span>
</template> </template>
</ms-table-column> </ms-table-column>
@ -253,6 +254,7 @@
@nextPage="nextPage" @nextPage="nextPage"
@prePage="prePage" @prePage="prePage"
@refresh="initTableData" @refresh="initTableData"
:test-case-names="testCaseNameArr"
:test-cases="tableData" :test-cases="tableData"
:is-read-only="isReadOnly" :is-read-only="isReadOnly"
:total="total" :total="total"
@ -324,6 +326,7 @@ export default {
fieldsWidth: getCustomTableWidth('TEST_PLAN_FUNCTION_TEST_CASE'), fieldsWidth: getCustomTableWidth('TEST_PLAN_FUNCTION_TEST_CASE'),
screenHeight: 'calc(100vh - 275px)', screenHeight: 'calc(100vh - 275px)',
tableLabel: [], tableLabel: [],
testCaseNameArr: [],
result: {}, result: {},
deletePath: "/test/case/delete", deletePath: "/test/case/delete",
condition: { condition: {
@ -536,8 +539,15 @@ export default {
callback(); callback();
} }
}); });
this.selectTestCaseName(this.condition);
} }
}, },
selectTestCaseName(condition){
this.result = this.$post("/test/plan/case/nameList", this.condition, response => {
let data = response.data;
this.testCaseNameArr = data;
});
},
autoCheckStatus() { autoCheckStatus() {
if (!this.planId) { if (!this.planId) {
return; return;
@ -672,7 +682,7 @@ export default {
getVersionOptions() { getVersionOptions() {
if (hasLicense()) { if (hasLicense()) {
this.$get('/project/version/get-project-versions/' + getCurrentProjectID(), response => { this.$get('/project/version/get-project-versions/' + getCurrentProjectID(), response => {
this.versionOptions= response.data; this.versionOptions = response.data;
this.versionFilters = response.data.map(u => { this.versionFilters = response.data.map(u => {
return {text: u.name, value: u.id}; return {text: u.name, value: u.id};
}); });