feat(接口测试): 场景列表增加定时任务展示列
--story=1011684 --user=宋天阳 接口场景列表、UI场景列表 展示定时任务列 https://www.tapd.cn/55049933/s/1360916
This commit is contained in:
parent
f34321b23c
commit
e68cfc62e9
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.api.dto;
|
||||
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ScheduleDTO extends Schedule {
|
||||
/**
|
||||
* 定时任务下一次执行时间
|
||||
*/
|
||||
private Long scheduleExecuteTime;
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.api.dto.ScheduleDTO;
|
||||
import io.metersphere.api.dto.definition.ApiSwaggerUrlDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.dto.TaskInfoResult;
|
||||
import io.metersphere.request.BaseQueryRequest;
|
||||
import io.metersphere.request.QueryScheduleRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -12,16 +11,12 @@ import java.util.List;
|
|||
public interface ExtScheduleMapper {
|
||||
List<ScheduleDao> list(@Param("request") QueryScheduleRequest request);
|
||||
|
||||
long countTaskByProjectId(String workspaceId);
|
||||
|
||||
long countTaskByProjectIdAndCreateTimeRange(@Param("projectId")String projectId, @Param("startTime") long startTime, @Param("endTime") long endTime);
|
||||
|
||||
List<TaskInfoResult> findRunningTaskInfoByProjectID(@Param("projectId") String workspaceID, @Param("request") BaseQueryRequest request);
|
||||
|
||||
void insert(@Param("apiSwaggerUrlDTO") ApiSwaggerUrlDTO apiSwaggerUrlDTO);
|
||||
|
||||
ApiSwaggerUrlDTO select(String id);
|
||||
ApiSwaggerUrlDTO select(String id);
|
||||
|
||||
int updateNameByResourceID(@Param("resourceId") String resourceId, @Param("name") String name);
|
||||
|
||||
List<ScheduleDTO> selectByResourceIds(@Param("ids") List<String> resourceIDs);
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
<insert id="insert" parameterType="io.metersphere.api.dto.definition.ApiSwaggerUrlDTO">
|
||||
insert into swagger_url_project (id, `project_id`, `swagger_url`,
|
||||
`schedule_id`)
|
||||
values (#{apiSwaggerUrlDTO.id,jdbcType=VARCHAR}, #{apiSwaggerUrlDTO.projectId,jdbcType=VARCHAR}, #{apiSwaggerUrlDTO.swaggerUrl,jdbcType=VARCHAR},
|
||||
values (#{apiSwaggerUrlDTO.id,jdbcType=VARCHAR}, #{apiSwaggerUrlDTO.projectId,jdbcType=VARCHAR},
|
||||
#{apiSwaggerUrlDTO.swaggerUrl,jdbcType=VARCHAR},
|
||||
#{apiSwaggerUrlDTO.scheduleId,jdbcType=VARCHAR})
|
||||
</insert>
|
||||
<select id="list" resultType="io.metersphere.dto.ScheduleDao">
|
||||
|
@ -48,41 +49,49 @@
|
|||
<select id="countTaskByProjectId" resultType="java.lang.Long">
|
||||
SELECT COUNT(id) AS countNumber
|
||||
FROM `schedule`
|
||||
WHERE resource_id IN (
|
||||
SELECT id FROM api_scenario WHERE project_id = #{0,jdbcType=VARCHAR} AND status != 'Trash' AND latest = 1
|
||||
)
|
||||
WHERE resource_id IN (SELECT id
|
||||
FROM api_scenario
|
||||
WHERE project_id = #{0,jdbcType=VARCHAR}
|
||||
AND status != 'Trash'
|
||||
AND latest = 1)
|
||||
</select>
|
||||
<select id="countTaskByProjectIdAndCreateTimeRange" resultType="java.lang.Long">
|
||||
SELECT COUNT(id) AS countNumber
|
||||
FROM `schedule`
|
||||
WHERE resource_id IN (
|
||||
SELECT scene.id
|
||||
FROM api_scenario scene
|
||||
WHERE scene.project_id = #{projectId,jdbcType=VARCHAR}
|
||||
AND scene.status != 'Trash' AND latest = 1
|
||||
)
|
||||
WHERE resource_id IN (SELECT scene.id
|
||||
FROM api_scenario scene
|
||||
WHERE scene.project_id = #{projectId,jdbcType=VARCHAR}
|
||||
AND scene.status != 'Trash'
|
||||
AND latest = 1)
|
||||
AND create_time BETWEEN #{startTime} AND #{endTime}
|
||||
</select>
|
||||
<select id="selectByResourceIds" resultType="io.metersphere.api.dto.ScheduleDTO">
|
||||
SELECT * FROM `schedule`
|
||||
WHERE resource_id IN
|
||||
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
||||
#{v}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="findRunningTaskInfoByProjectID" resultType="io.metersphere.dto.TaskInfoResult">
|
||||
SELECT sch.id AS taskID,
|
||||
sch.`name` AS `name`,
|
||||
sch.`value` AS rule,
|
||||
sch.`enable` AS `taskStatus`,
|
||||
sch.update_time AS updateTime,
|
||||
sch.id AS taskID,
|
||||
sch.`value` AS rule,
|
||||
sch.`enable` AS `taskStatus`,
|
||||
u.`name` AS creator,
|
||||
sch.update_time AS updateTime,
|
||||
sch.type AS taskType,
|
||||
sch.`group` AS taskGroup,
|
||||
sch.resource_id AS scenarioId
|
||||
sch.`name` AS `name`,
|
||||
sch.`value` AS rule,
|
||||
sch.`enable` AS `taskStatus`,
|
||||
sch.update_time AS updateTime,
|
||||
sch.id AS taskID,
|
||||
sch.`value` AS rule,
|
||||
sch.`enable` AS `taskStatus`,
|
||||
u.`name` AS creator,
|
||||
sch.update_time AS updateTime,
|
||||
sch.type AS taskType,
|
||||
sch.`group` AS taskGroup,
|
||||
sch.resource_id AS scenarioId
|
||||
FROM (
|
||||
schedule sch left join user u
|
||||
ON sch.user_id = u.id
|
||||
schedule sch left join user u
|
||||
ON sch.user_id = u.id
|
||||
)
|
||||
WHERE sch.`enable` = true
|
||||
AND sch.project_id = #{projectId,jdbcType=VARCHAR}
|
||||
AND sch.project_id = #{projectId,jdbcType=VARCHAR}
|
||||
|
||||
<if test="request.filters != null and request.filters.size() > 0">
|
||||
<foreach collection="request.filters.entrySet()" index="key" item="values">
|
||||
|
@ -100,9 +109,13 @@
|
|||
</if>
|
||||
</select>
|
||||
<select id="select" resultType="io.metersphere.api.dto.definition.ApiSwaggerUrlDTO">
|
||||
select * from swagger_url_project where id=#{id}
|
||||
select *
|
||||
from swagger_url_project
|
||||
where id = #{id}
|
||||
</select>
|
||||
<update id="updateNameByResourceID">
|
||||
update schedule set name = #{name} where resource_id = #{resourceId}
|
||||
update schedule
|
||||
set name = #{name}
|
||||
where resource_id = #{resourceId}
|
||||
</update>
|
||||
</mapper>
|
||||
|
|
|
@ -24,6 +24,7 @@ import io.metersphere.request.ResetOrderRequest;
|
|||
import io.metersphere.service.ext.ExtApiTaskService;
|
||||
import io.metersphere.service.scenario.ApiScenarioService;
|
||||
import io.metersphere.task.dto.TaskRequestDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
|
@ -34,7 +35,6 @@ import org.springframework.http.ResponseEntity;
|
|||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -57,6 +57,12 @@ public class ApiScenarioController {
|
|||
return PageUtils.setPageInfo(page, apiAutomationService.list(request));
|
||||
}
|
||||
|
||||
@PostMapping("/scenario/schedule")
|
||||
@RequiresPermissions("PROJECT_API_SCENARIO:READ")
|
||||
public Map<String, ScheduleDTO> scenarioScheduleInfo(@RequestBody List<String> scenarioIds) {
|
||||
return apiAutomationService.selectScheduleInfo(scenarioIds);
|
||||
}
|
||||
|
||||
@PostMapping("/list")
|
||||
@RequiresPermissions("PROJECT_API_SCENARIO:READ")
|
||||
public List<ApiScenarioDTO> listAll(@RequestBody ApiScenarioRequest request) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.service.ext;
|
||||
|
||||
import io.metersphere.api.dto.ScheduleDTO;
|
||||
import io.metersphere.api.dto.ScheduleRequest;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ScheduleMapper;
|
||||
|
@ -22,6 +23,8 @@ import io.metersphere.sechedule.ApiScenarioTestJob;
|
|||
import io.metersphere.sechedule.ScheduleManager;
|
||||
import io.metersphere.sechedule.SwaggerUrlImportJob;
|
||||
import io.metersphere.service.ServiceUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.SchedulerException;
|
||||
|
@ -29,10 +32,10 @@ import org.quartz.TriggerKey;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
@ -233,4 +236,12 @@ public class ExtApiScheduleService {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public List<ScheduleDTO> selectByResourceIds(List<String> scenarioIds) {
|
||||
if (CollectionUtils.isNotEmpty(scenarioIds)) {
|
||||
return extScheduleMapper.selectByResourceIds(scenarioIds);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import io.metersphere.api.dto.definition.ApiTestCaseInfo;
|
|||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.request.*;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.request.unknown.MsJmeterElement;
|
||||
import io.metersphere.api.dto.export.ScenarioToPerformanceInfoDTO;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioParamDTO;
|
||||
import io.metersphere.api.exec.scenario.ApiScenarioEnvService;
|
||||
|
@ -71,6 +70,10 @@ import org.jetbrains.annotations.NotNull;
|
|||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.quartz.CronExpression;
|
||||
import org.quartz.CronScheduleBuilder;
|
||||
import org.quartz.CronTrigger;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -2325,4 +2328,26 @@ public class ApiScenarioService {
|
|||
}
|
||||
|
||||
|
||||
public Map<String, ScheduleDTO> selectScheduleInfo(List<String> scenarioIds) {
|
||||
if (CollectionUtils.isNotEmpty(scenarioIds)) {
|
||||
List<ScheduleDTO> scheduleInfoList = scheduleService.selectByResourceIds(scenarioIds);
|
||||
for (ScheduleDTO schedule : scheduleInfoList) {
|
||||
schedule.setScheduleExecuteTime(this.getNextTriggerTime(schedule.getValue()));
|
||||
}
|
||||
return scheduleInfoList.stream().collect(Collectors.toMap(Schedule::getResourceId, item -> item));
|
||||
} else {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
//获取下次执行时间(getFireTimeAfter,也可以下下次...)
|
||||
private long getNextTriggerTime(String cron) {
|
||||
if (!CronExpression.isValidExpression(cron)) {
|
||||
return 0;
|
||||
}
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("Calculate Date").withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
|
||||
Date time0 = trigger.getStartTime();
|
||||
Date time1 = trigger.getFireTimeAfter(time0);
|
||||
return time1 == null ? 0 : time1.getTime();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@ export function getScenarioList(currentPage, pageSize, condition) {
|
|||
return post(url, condition);
|
||||
}
|
||||
|
||||
export function getScheduleDetail(scenarioIds) {
|
||||
let url = '/api/automation/scenario/schedule';
|
||||
return post(url, scenarioIds);
|
||||
}
|
||||
|
||||
export function getScenarioByTrash(condition) {
|
||||
return post('/api/automation/list/all/trash', condition);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
:fields-width="fieldsWidth"
|
||||
v-if="this.trashEnable"
|
||||
:label="$t('commons.delete_user')"
|
||||
min-width="120"/>
|
||||
min-width="120" />
|
||||
|
||||
<span v-for="item in fields" :key="item.key">
|
||||
<ms-table-column
|
||||
|
@ -81,7 +81,7 @@
|
|||
:label="$t('api_test.automation.scenario_name')"
|
||||
min-width="150px"
|
||||
prop="name"
|
||||
sortable/>
|
||||
sortable />
|
||||
|
||||
<ms-table-column
|
||||
:field="item"
|
||||
|
@ -92,7 +92,7 @@
|
|||
prop="level"
|
||||
sortable>
|
||||
<template v-slot:default="scope">
|
||||
<priority-table-item :value="scope.row.level"/>
|
||||
<priority-table-item :value="scope.row.level" />
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
|
@ -105,7 +105,7 @@
|
|||
prop="status"
|
||||
min-width="120px">
|
||||
<template v-slot:default="scope">
|
||||
<plan-status-table-item :value="scope.row.status"/>
|
||||
<plan-status-table-item :value="scope.row.status" />
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
|
@ -117,20 +117,20 @@
|
|||
min-width="120px"
|
||||
prop="tags">
|
||||
<template v-slot:default="scope">
|
||||
<el-tooltip class="item" effect="dark" placement="top">
|
||||
<div v-html="getTagToolTips(scope.row.tags)" slot="content"></div>
|
||||
<div class="oneLine">
|
||||
<ms-tag
|
||||
v-for="(itemName, index) in scope.row.tags"
|
||||
:key="index"
|
||||
type="success"
|
||||
effect="plain"
|
||||
:show-tooltip="scope.row.tags.length === 1 && itemName.length * 12 <= 100"
|
||||
:content="itemName"
|
||||
style="margin-left: 0px; margin-right: 2px" />
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-tooltip class="item" effect="dark" placement="top">
|
||||
<div v-html="getTagToolTips(scope.row.tags)" slot="content"></div>
|
||||
<div class="oneLine">
|
||||
<ms-tag
|
||||
v-for="(itemName, index) in scope.row.tags"
|
||||
:key="index"
|
||||
type="success"
|
||||
effect="plain"
|
||||
:show-tooltip="scope.row.tags.length === 1 && itemName.length * 12 <= 100"
|
||||
:content="itemName"
|
||||
style="margin-left: 0px; margin-right: 2px" />
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column
|
||||
|
@ -151,7 +151,7 @@
|
|||
:fields-width="fieldsWidth"
|
||||
prop="principalName"
|
||||
min-width="120px"
|
||||
sortable/>
|
||||
sortable />
|
||||
<ms-table-column
|
||||
:label="$t('api_test.automation.creator')"
|
||||
:filters="userFilters"
|
||||
|
@ -159,7 +159,7 @@
|
|||
:fields-width="fieldsWidth"
|
||||
prop="creatorName"
|
||||
min-width="120px"
|
||||
sortable="custom"/>
|
||||
sortable="custom" />
|
||||
<ms-table-column
|
||||
:field="item"
|
||||
:fields-width="fieldsWidth"
|
||||
|
@ -176,25 +176,41 @@
|
|||
<el-tag type="success" size="mini" effect="plain">
|
||||
<span class="project-env" :title="k">{{ k }}</span>
|
||||
</el-tag>
|
||||
<br/>
|
||||
<br />
|
||||
</span>
|
||||
<el-popover placement="top" width="350" trigger="click">
|
||||
<div v-for="(k, v, index) in row.environmentMap" :key="index">
|
||||
<span class="plan-case-env" :title="v">{{ v }}</span
|
||||
>:
|
||||
<el-tag type="success" size="mini" effect="plain">
|
||||
<span class="project-env" style="margin: 0 0 0 5px" :title="k">{{ k }}
|
||||
</span>
|
||||
</el-tag>
|
||||
<br/>
|
||||
<el-tag type="success" size="mini" effect="plain">
|
||||
<span class="project-env" style="margin: 0 0 0 5px" :title="k">{{ k }} </span>
|
||||
</el-tag>
|
||||
<br />
|
||||
</div>
|
||||
<el-link v-if="index === 1" slot="reference" type="info" :underline="false" icon="el-icon-more"/>
|
||||
<el-link v-if="index === 1" slot="reference" type="info" :underline="false" icon="el-icon-more" />
|
||||
</el-popover>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column
|
||||
:label="$t('commons.trigger_mode.schedule')"
|
||||
:field="item"
|
||||
:fields-width="fieldsWidth"
|
||||
min-width="100px"
|
||||
prop="schedule">
|
||||
<template v-slot:default="scope">
|
||||
<schedule-info-in-table
|
||||
v-if="scope.row.scheduleObj"
|
||||
@openSchedule="openSchedule(scope.row)"
|
||||
@scheduleChange="scheduleStatusChange"
|
||||
@refreshTable="nodeChange"
|
||||
:scenario="scope.row"
|
||||
:request="runRequest"
|
||||
:schedule="scope.row.scheduleObj" />
|
||||
<i v-else class="el-icon-loading" />
|
||||
</template>
|
||||
</ms-table-column>
|
||||
<ms-table-column
|
||||
:field="item"
|
||||
:fields-width="fieldsWidth"
|
||||
|
@ -223,7 +239,7 @@
|
|||
:fields-width="fieldsWidth"
|
||||
:label="$t('api_test.automation.step')"
|
||||
prop="stepTotal"
|
||||
min-width="80px"/>
|
||||
min-width="80px" />
|
||||
<ms-table-column
|
||||
:label="$t('api_test.automation.last_result')"
|
||||
:filters="resultFilters"
|
||||
|
@ -234,7 +250,7 @@
|
|||
min-width="130px">
|
||||
<template v-slot:default="{ row }">
|
||||
<el-link @click="showReport(row)" :disabled="!row.lastResult || row.lastResult === 'PENDING'">
|
||||
<ms-api-report-status :status="row.lastResult"/>
|
||||
<ms-api-report-status :status="row.lastResult" />
|
||||
</el-link>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
@ -244,7 +260,7 @@
|
|||
:fields-width="fieldsWidth"
|
||||
:label="$t('api_test.automation.passing_rate')"
|
||||
prop="passRate"
|
||||
min-width="120px"/>
|
||||
min-width="120px" />
|
||||
</span>
|
||||
|
||||
<template v-slot:opt-before="scope">
|
||||
|
@ -255,7 +271,7 @@
|
|||
icon="el-icon-video-play"
|
||||
class="run-button"
|
||||
style="margin-right: 10px"
|
||||
v-permission="['PROJECT_API_SCENARIO:READ+RUN']"/>
|
||||
v-permission="['PROJECT_API_SCENARIO:READ+RUN']" />
|
||||
<el-tooltip :content="$t('report.stop_btn')" placement="top" :enterable="false" v-else>
|
||||
<el-button
|
||||
v-if="!trashEnable"
|
||||
|
@ -279,11 +295,11 @@
|
|||
@openScenario="openScenario"
|
||||
@showCaseRef="showScenarioRef"
|
||||
v-if="!trashEnable"
|
||||
style="display: contents"/>
|
||||
style="display: contents" />
|
||||
</template>
|
||||
</ms-table>
|
||||
|
||||
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total"/>
|
||||
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total" />
|
||||
|
||||
<div>
|
||||
<!-- 执行结果 -->
|
||||
|
@ -301,7 +317,7 @@
|
|||
:scenarioId="scenarioId"
|
||||
:infoDb="infoDb"
|
||||
:report-id="reportId"
|
||||
:currentProjectId="projectId"/>
|
||||
:currentProjectId="projectId" />
|
||||
</el-drawer>
|
||||
<!-- 执行结果 -->
|
||||
<el-drawer
|
||||
|
@ -317,7 +333,7 @@
|
|||
:infoDb="infoDb"
|
||||
:show-cancel-button="false"
|
||||
:report-id="showReportId"
|
||||
:currentProjectId="projectId"/>
|
||||
:currentProjectId="projectId" />
|
||||
</el-drawer>
|
||||
<!--测试计划-->
|
||||
<el-drawer
|
||||
|
@ -333,7 +349,7 @@
|
|||
@cancel="cancel"
|
||||
ref="testPlanList"
|
||||
:scenario-condition="condition"
|
||||
:row="selectRows"/>
|
||||
:row="selectRows" />
|
||||
</el-drawer>
|
||||
</div>
|
||||
|
||||
|
@ -342,14 +358,14 @@
|
|||
@batchEdit="batchEdit"
|
||||
:typeArr="typeArr"
|
||||
:value-arr="valueArr"
|
||||
:dialog-title="$t('test_track.case.batch_edit_case')"/>
|
||||
<batch-move @refresh="search" @moveSave="moveSave" ref="testBatchMove"/>
|
||||
:dialog-title="$t('test_track.case.batch_edit_case')" />
|
||||
<batch-move @refresh="search" @moveSave="moveSave" ref="testBatchMove" />
|
||||
<ms-api-run-mode
|
||||
:request="runRequest"
|
||||
:project-id="projectId"
|
||||
@close="search"
|
||||
@handleRunBatch="handleRunBatch"
|
||||
ref="apiBatchRun"/>
|
||||
ref="apiBatchRun" />
|
||||
<ms-run
|
||||
:debug="true"
|
||||
:environment="projectEnvMap"
|
||||
|
@ -361,20 +377,20 @@
|
|||
:run-data="debugData"
|
||||
@runRefresh="runRefresh"
|
||||
@errorRefresh="errorRefresh"
|
||||
ref="runTest"/>
|
||||
<ms-task-center ref="taskCenter" :show-menu="false"/>
|
||||
<relationship-graph-drawer :graph-data="graphData" ref="relationshipGraph"/>
|
||||
ref="runTest" />
|
||||
<ms-task-center ref="taskCenter" :show-menu="false" />
|
||||
<relationship-graph-drawer :graph-data="graphData" ref="relationshipGraph" />
|
||||
<!-- 删除接口提示 -->
|
||||
<scenario-delete-confirm ref="apiDeleteConfirmVersion" @handleDelete="_handleDelete"/>
|
||||
<scenario-delete-confirm ref="apiDeleteConfirmVersion" @handleDelete="_handleDelete" />
|
||||
<!-- 删除场景弹窗 -->
|
||||
<api-delete-confirm
|
||||
:has-ref="hasRef"
|
||||
:show-scenario="showScenario"
|
||||
@showCaseRef="showScenarioRef"
|
||||
@handleDeleteCase="handleDeleteScenario"
|
||||
ref="apiDeleteConfirm"/>
|
||||
ref="apiDeleteConfirm" />
|
||||
<!-- 引用场景弹窗 -->
|
||||
<ms-show-reference ref="viewRef" @showCaseRef="showScenarioRef" @openScenario="openScenario"/>
|
||||
<ms-show-reference ref="viewRef" @showCaseRef="showScenarioRef" @openScenario="openScenario" />
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
@ -395,6 +411,7 @@ import {
|
|||
getScenarioList,
|
||||
getScenarioVersions,
|
||||
getScenarioWithBLOBsById,
|
||||
getScheduleDetail,
|
||||
listWithIds,
|
||||
removeScenarioToGcByBatch,
|
||||
runBatch,
|
||||
|
@ -404,13 +421,13 @@ import {
|
|||
scenarioRun,
|
||||
updateScenarioEnv,
|
||||
} from '@/api/scenario';
|
||||
import {getMaintainer, getProject} from '@/api/project';
|
||||
import {getProjectVersions, versionEnableByProjectId} from '@/api/xpack';
|
||||
import {getCurrentProjectID, getCurrentUserId} from 'metersphere-frontend/src/utils/token';
|
||||
import {downloadFile, getUUID, objToStrMap, strMapToObj} from 'metersphere-frontend/src/utils';
|
||||
import {hasLicense, hasPermission} from 'metersphere-frontend/src/utils/permission';
|
||||
import {API_SCENARIO_CONFIGS} from 'metersphere-frontend/src/components/search/search-components';
|
||||
import {API_SCENARIO_LIST} from 'metersphere-frontend/src/utils/constants';
|
||||
import { getMaintainer, getProject } from '@/api/project';
|
||||
import { getProjectVersions, versionEnableByProjectId } from '@/api/xpack';
|
||||
import { getCurrentProjectID, getCurrentUserId } from 'metersphere-frontend/src/utils/token';
|
||||
import { downloadFile, getUUID, objToStrMap, strMapToObj } from 'metersphere-frontend/src/utils';
|
||||
import { hasLicense, hasPermission } from 'metersphere-frontend/src/utils/permission';
|
||||
import { API_SCENARIO_CONFIGS } from 'metersphere-frontend/src/components/search/search-components';
|
||||
import { API_SCENARIO_LIST } from 'metersphere-frontend/src/utils/constants';
|
||||
import {
|
||||
buildBatchParam,
|
||||
getCustomTableHeader,
|
||||
|
@ -418,27 +435,29 @@ import {
|
|||
getLastTableSortField,
|
||||
getSelectDataCounts,
|
||||
} from 'metersphere-frontend/src/utils/tableUtils';
|
||||
import {API_SCENARIO_FILTERS} from 'metersphere-frontend/src/utils/table-constants';
|
||||
import { API_SCENARIO_FILTERS } from 'metersphere-frontend/src/utils/table-constants';
|
||||
import MsTable from 'metersphere-frontend/src/components/table/MsTable';
|
||||
import MsTableColumn from 'metersphere-frontend/src/components/table/MsTableColumn';
|
||||
import HeaderLabelOperate from 'metersphere-frontend/src/components/head/HeaderLabelOperate';
|
||||
import {getGraphByCondition} from '@/api/graph';
|
||||
import {API_SCENARIO_CONFIGS_TRASH, TYPE_TO_C} from '@/business/automation/scenario/Setting';
|
||||
import { getGraphByCondition } from '@/api/graph';
|
||||
import { API_SCENARIO_CONFIGS_TRASH, TYPE_TO_C } from '@/business/automation/scenario/Setting';
|
||||
import MsTableSearchBar from 'metersphere-frontend/src/components/MsTableSearchBar';
|
||||
import MsTableAdvSearchBar from 'metersphere-frontend/src/components/search/MsTableAdvSearchBar';
|
||||
import ListItemDeleteConfirm from 'metersphere-frontend/src/components/ListItemDeleteConfirm';
|
||||
import ScenarioDeleteConfirm from '@/business/automation/scenario/ScenarioDeleteConfirm';
|
||||
import {$error} from 'metersphere-frontend/src/plugins/message';
|
||||
import { $error } from 'metersphere-frontend/src/plugins/message';
|
||||
import MsSearch from 'metersphere-frontend/src/components/search/MsSearch';
|
||||
import {buildNodePath} from 'metersphere-frontend/src/model/NodeTree';
|
||||
import {getEnvironmentByProjectId} from 'metersphere-frontend/src/api/environment';
|
||||
import {REPORT_STATUS} from '@/business/commons/js/commons';
|
||||
import {usePerformanceStore} from '@/store';
|
||||
import {request} from 'metersphere-frontend/src/plugins/request';
|
||||
import {parseEnvironment} from '@/business/environment/model/EnvironmentModel';
|
||||
import { buildNodePath } from 'metersphere-frontend/src/model/NodeTree';
|
||||
import { getEnvironmentByProjectId } from 'metersphere-frontend/src/api/environment';
|
||||
import { REPORT_STATUS } from '@/business/commons/js/commons';
|
||||
import { usePerformanceStore } from '@/store';
|
||||
import { request } from 'metersphere-frontend/src/plugins/request';
|
||||
import { parseEnvironment } from '@/business/environment/model/EnvironmentModel';
|
||||
import MsApiRunMode from '@/business/automation/scenario/common/ApiRunMode';
|
||||
import ApiDeleteConfirm from '@/business/definition/components/list/ApiDeleteConfirm';
|
||||
import MsShowReference from '@/business/definition/components/reference/ShowReference';
|
||||
import scheduleInfoInTable from '@/business/automation/schedule/ScheduleInfoInTable.vue';
|
||||
import { scheduleUpdate } from '@/api/schedule';
|
||||
|
||||
const performanceStore = usePerformanceStore();
|
||||
export default {
|
||||
|
@ -455,6 +474,7 @@ export default {
|
|||
ApiDeleteConfirm,
|
||||
MsShowReference,
|
||||
ScenarioDeleteConfirm,
|
||||
scheduleInfoInTable,
|
||||
MsApiReportStatus: () => import('../report/ApiReportStatus'),
|
||||
HeaderCustom: () => import('metersphere-frontend/src/components/head/HeaderCustom'),
|
||||
BatchMove: () => import('@/business/commons/BatchMove'),
|
||||
|
@ -657,8 +677,8 @@ export default {
|
|||
},
|
||||
],
|
||||
typeArr: [
|
||||
{id: 'level', name: this.$t('test_track.case.priority')},
|
||||
{id: 'status', name: this.$t('test_track.plan.plan_status')},
|
||||
{ id: 'level', name: this.$t('test_track.case.priority') },
|
||||
{ id: 'status', name: this.$t('test_track.plan.plan_status') },
|
||||
{
|
||||
id: 'principal',
|
||||
name: this.$t('api_test.definition.request.responsible'),
|
||||
|
@ -669,14 +689,14 @@ export default {
|
|||
id: 'projectEnv',
|
||||
name: this.$t('api_test.definition.request.run_env'),
|
||||
},
|
||||
{id: 'tags', name: this.$t('commons.tag')},
|
||||
{ id: 'tags', name: this.$t('commons.tag') },
|
||||
],
|
||||
valueArr: {
|
||||
level: [
|
||||
{name: 'P0', id: 'P0'},
|
||||
{name: 'P1', id: 'P1'},
|
||||
{name: 'P2', id: 'P2'},
|
||||
{name: 'P3', id: 'P3'},
|
||||
{ name: 'P0', id: 'P0' },
|
||||
{ name: 'P1', id: 'P1' },
|
||||
{ name: 'P2', id: 'P2' },
|
||||
{ name: 'P3', id: 'P3' },
|
||||
],
|
||||
status: [
|
||||
{
|
||||
|
@ -717,10 +737,10 @@ export default {
|
|||
if (!this.projectName || this.projectName === '') {
|
||||
this.getProjectName();
|
||||
}
|
||||
this.condition.filters = {status: ['Prepare', 'Underway', 'Completed']};
|
||||
this.condition.filters = { status: ['Prepare', 'Underway', 'Completed'] };
|
||||
this.initEnvironment();
|
||||
if (this.trashEnable) {
|
||||
this.condition.filters = {status: ['Trash']};
|
||||
this.condition.filters = { status: ['Trash'] };
|
||||
this.condition.moduleIds = [];
|
||||
this.operators = this.trashOperators;
|
||||
this.buttons = this.trashButtons;
|
||||
|
@ -735,7 +755,7 @@ export default {
|
|||
}
|
||||
|
||||
if (this.trashEnable) {
|
||||
this.condition.orders = [{name: 'delete_time', type: 'desc'}];
|
||||
this.condition.orders = [{ name: 'delete_time', type: 'desc' }];
|
||||
} else {
|
||||
this.condition.orders = getLastTableSortField(this.tableHeaderKey);
|
||||
}
|
||||
|
@ -768,7 +788,7 @@ export default {
|
|||
},
|
||||
trashEnable() {
|
||||
if (this.trashEnable) {
|
||||
this.condition.filters = {status: ['Trash']};
|
||||
this.condition.filters = { status: ['Trash'] };
|
||||
this.condition.moduleIds = [];
|
||||
this.operators = this.trashOperators;
|
||||
this.buttons = this.trashButtons;
|
||||
|
@ -797,7 +817,7 @@ export default {
|
|||
moduleOptionsNew() {
|
||||
let moduleOptions = [];
|
||||
this.moduleOptions.forEach((node) => {
|
||||
buildNodePath(node, {path: ''}, moduleOptions);
|
||||
buildNodePath(node, { path: '' }, moduleOptions);
|
||||
});
|
||||
return moduleOptions;
|
||||
},
|
||||
|
@ -829,12 +849,12 @@ export default {
|
|||
parseEnvironment(environment);
|
||||
});
|
||||
this.environmentsFilters = response.data.map((u) => {
|
||||
return {text: u.name, value: u.id};
|
||||
return { text: u.name, value: u.id };
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
search(projectId){
|
||||
search(projectId) {
|
||||
this.$EventBus.$emit('scenarioConditionBus', this.condition);
|
||||
this.nodeChange(projectId);
|
||||
},
|
||||
|
@ -915,7 +935,9 @@ export default {
|
|||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
let ids = [];
|
||||
this.tableData.forEach((item) => {
|
||||
ids.push(item.id);
|
||||
if (item.tags && item.tags.length > 0) {
|
||||
item.tags = JSON.parse(item.tags);
|
||||
}
|
||||
|
@ -924,9 +946,59 @@ export default {
|
|||
if (this.$refs.scenarioTable) {
|
||||
this.$refs.scenarioTable.clearSelection();
|
||||
}
|
||||
this.selectSchedule(ids);
|
||||
});
|
||||
}
|
||||
},
|
||||
selectSchedule(ids) {
|
||||
if (ids.length > 0) {
|
||||
getScheduleDetail(ids).then((response) => {
|
||||
if (response.data) {
|
||||
let scheduleData = response.data;
|
||||
this.tableData.forEach((scenario) => {
|
||||
let scheduleInfo = this.getScheduleObject(scheduleData[scenario.id], scenario.id);
|
||||
this.$set(scenario, 'scheduleObj', scheduleInfo);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
scheduleStatusChange(schedule) {
|
||||
let scheduleRequest = {
|
||||
taskID: schedule.id,
|
||||
enable: schedule.enable,
|
||||
};
|
||||
this.result = scheduleUpdate(scheduleRequest)
|
||||
.then(() => {
|
||||
schedule.scheduleStatus = schedule.enable ? 'OPEN' : 'SHUT';
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
})
|
||||
.catch(() => {
|
||||
this.$success(this.$t('commons.save_failed'));
|
||||
schedule.enable = !schedule.enable;
|
||||
});
|
||||
},
|
||||
getScheduleObject(schedule, resourceId) {
|
||||
if (schedule) {
|
||||
return {
|
||||
scheduleStatus: schedule.enable ? 'OPEN' : 'SHUT',
|
||||
scheduleCorn: schedule.value,
|
||||
scheduleExecuteTime: schedule.scheduleExecuteTime,
|
||||
enable: schedule.enable,
|
||||
id: schedule.id,
|
||||
resourceId: schedule.resourceId,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
scheduleStatus: '',
|
||||
scheduleCorn: '',
|
||||
scheduleExecuteTime: '',
|
||||
enable: false,
|
||||
id: '',
|
||||
resourceId: resourceId,
|
||||
};
|
||||
}
|
||||
},
|
||||
handleCommand(cmd) {
|
||||
let table = this.$refs.scenarioTable;
|
||||
switch (cmd) {
|
||||
|
@ -1019,7 +1091,7 @@ export default {
|
|||
getMaintainer().then((response) => {
|
||||
option.push(...response.data);
|
||||
this.userFilters = response.data.map((u) => {
|
||||
return {text: u.name, value: u.id};
|
||||
return { text: u.name, value: u.id };
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -1030,11 +1102,11 @@ export default {
|
|||
this.versionFilters = response.data
|
||||
.filter((u) => u.id === currentVersion)
|
||||
.map((u) => {
|
||||
return {text: u.name, value: u.id};
|
||||
return { text: u.name, value: u.id };
|
||||
});
|
||||
} else {
|
||||
this.versionFilters = response.data.map((u) => {
|
||||
return {text: u.name, value: u.id};
|
||||
return { text: u.name, value: u.id };
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1125,7 +1197,7 @@ export default {
|
|||
|
||||
handleRunBatch(config) {
|
||||
this.infoDb = false;
|
||||
let run = {config: config};
|
||||
let run = { config: config };
|
||||
run.id = getUUID();
|
||||
//按照列表排序
|
||||
let ids = this.orderBySelectRows();
|
||||
|
@ -1421,7 +1493,7 @@ export default {
|
|||
this.search();
|
||||
});
|
||||
} else {
|
||||
let param = {ids: [api.id]};
|
||||
let param = { ids: [api.id] };
|
||||
removeScenarioToGcByBatch(param).then(() => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.$refs.apiDeleteConfirmVersion.close();
|
||||
|
@ -1460,7 +1532,7 @@ export default {
|
|||
method: 'post',
|
||||
data: param,
|
||||
responseType: 'blob',
|
||||
headers: {'Content-Type': 'application/json; charset=utf-8'},
|
||||
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
||||
};
|
||||
request(config).then(
|
||||
(response) => {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<div v-if="schedule">
|
||||
<span v-if="schedule.scheduleStatus === 'OPEN'">
|
||||
<el-tooltip placement="bottom-start" effect="light">
|
||||
<div slot="content">
|
||||
{{ $t('home.table.run_rule') }}: {{ schedule.scheduleCorn }}<br />
|
||||
{{ $t('test_track.plan.next_run_time') }}:<span>{{ schedule.scheduleExecuteTime | datetimeFormat }}</span>
|
||||
</div>
|
||||
<el-switch
|
||||
@click.stop.native
|
||||
v-model="schedule.enable"
|
||||
inactive-color="#DCDFE6"
|
||||
@change="scheduleChange"
|
||||
:disabled="hasPermission">
|
||||
</el-switch>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span v-else-if="schedule.scheduleStatus === 'SHUT'">
|
||||
<el-switch
|
||||
@click.stop.native
|
||||
v-model="schedule.enable"
|
||||
inactive-color="#DCDFE6"
|
||||
@change="scheduleChange"
|
||||
:disabled="hasPermission">
|
||||
</el-switch>
|
||||
</span>
|
||||
<span v-else>
|
||||
<el-link @click.stop="scheduleTask" :disabled="hasPermission" style="color: #783887">{{
|
||||
$t('schedule.not_set')
|
||||
}}</el-link>
|
||||
</span>
|
||||
|
||||
<ms-schedule-maintain ref="scheduleMaintain" @refreshTable="refreshTable" :request="request" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { operationConfirm } from 'metersphere-frontend/src/utils';
|
||||
import MsScheduleMaintain from '@/business/automation/schedule/ScheduleMaintain.vue';
|
||||
|
||||
export default {
|
||||
name: 'ScheduleInfoInTable',
|
||||
components: { MsScheduleMaintain },
|
||||
props: {
|
||||
schedule: Object,
|
||||
hasPermission: Boolean,
|
||||
scenario: Object,
|
||||
request: {},
|
||||
},
|
||||
methods: {
|
||||
scheduleTask() {
|
||||
this.$emit('openSchedule');
|
||||
this.$refs.scheduleMaintain.open(this.scenario);
|
||||
},
|
||||
refreshTable() {
|
||||
this.$emit('refreshTable');
|
||||
},
|
||||
scheduleChange() {
|
||||
let message = this.$t('api_test.home_page.running_task_list.confirm.close_title');
|
||||
if (this.schedule.enable) {
|
||||
message = this.$t('api_test.home_page.running_task_list.confirm.open_title');
|
||||
}
|
||||
operationConfirm(
|
||||
this,
|
||||
message,
|
||||
() => {
|
||||
this.$emit('scheduleChange', this.schedule);
|
||||
},
|
||||
() => {
|
||||
this.schedule.enable = !this.schedule.enable;
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -1,190 +1,220 @@
|
|||
export const TEST_CASE_LIST = 'test_case_list';
|
||||
export const TEST_CASE_LIST = "test_case_list";
|
||||
|
||||
export const CUSTOM_FIELD_LIST = new Set([
|
||||
'name',
|
||||
'scene',
|
||||
'type',
|
||||
'remark',
|
||||
'system',
|
||||
'createTime',
|
||||
'updateTime'
|
||||
"name",
|
||||
"scene",
|
||||
"type",
|
||||
"remark",
|
||||
"system",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
]);
|
||||
|
||||
|
||||
export const ISSUE_TEMPLATE_LIST = new Set([
|
||||
'name',
|
||||
'platform',
|
||||
'description',
|
||||
'createTime',
|
||||
'updateTime'
|
||||
"name",
|
||||
"platform",
|
||||
"description",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
]);
|
||||
|
||||
export let CUSTOM_TABLE_HEADER = {
|
||||
|
||||
CUSTOM_FIELD: [
|
||||
{id: 'name', key: '1', label: 'commons.name'},
|
||||
{id: 'scene', key: '2', label: 'custom_field.scene'},
|
||||
{id: 'type', key: '3', label: 'custom_field.attribute_type'},
|
||||
{id: 'remark', key: '4', label: 'commons.remark'},
|
||||
{id: 'system', key: '5', label: 'custom_field.system_field'},
|
||||
{id: 'createTime', key: '6', label: 'commons.create_time'},
|
||||
{id: 'updateTime', key: '7', label: 'commons.update_time'},
|
||||
{ id: "name", key: "1", label: "commons.name" },
|
||||
{ id: "scene", key: "2", label: "custom_field.scene" },
|
||||
{ id: "type", key: "3", label: "custom_field.attribute_type" },
|
||||
{ id: "remark", key: "4", label: "commons.remark" },
|
||||
{ id: "system", key: "5", label: "custom_field.system_field" },
|
||||
{ id: "createTime", key: "6", label: "commons.create_time" },
|
||||
{ id: "updateTime", key: "7", label: "commons.update_time" },
|
||||
],
|
||||
//接口定义
|
||||
API_DEFINITION: [
|
||||
{id: 'num', key: '1', label: "ID"},
|
||||
{id: 'name', key: '2', label: 'api_test.definition.api_name'},
|
||||
{id: 'method', key: '3', label: 'api_test.definition.api_type'},
|
||||
{id: 'userName', key: '4', label: 'api_test.definition.api_principal'},
|
||||
{id: 'path', key: '5', label: 'api_test.definition.api_path'},
|
||||
{id: 'tags', key: '6', label: 'commons.tag'},
|
||||
{id: 'versionId', key: 'f', label: 'project.version.name', xpack: true},
|
||||
{id: 'updateTime', key: '7', label: 'api_test.definition.api_last_time'},
|
||||
{id: 'caseTotal', key: '8', label: 'api_test.definition.api_case_number'},
|
||||
{id: 'caseStatus', key: '9', label: 'api_test.definition.api_case_status'},
|
||||
{id: 'casePassingRate', key: 'a', label: 'api_test.definition.api_case_passing_rate'},
|
||||
{id: 'status', key: 'b', label: 'api_test.definition.api_status'},
|
||||
{id: 'createTime', key: 'c', label: 'commons.create_time'},
|
||||
{id: 'description', key: 'e', label: 'commons.description'},
|
||||
{ id: "num", key: "1", label: "ID" },
|
||||
{ id: "name", key: "2", label: "api_test.definition.api_name" },
|
||||
{ id: "method", key: "3", label: "api_test.definition.api_type" },
|
||||
{ id: "userName", key: "4", label: "api_test.definition.api_principal" },
|
||||
{ id: "path", key: "5", label: "api_test.definition.api_path" },
|
||||
{ id: "tags", key: "6", label: "commons.tag" },
|
||||
{ id: "versionId", key: "f", label: "project.version.name", xpack: true },
|
||||
{ id: "updateTime", key: "7", label: "api_test.definition.api_last_time" },
|
||||
{ id: "caseTotal", key: "8", label: "api_test.definition.api_case_number" },
|
||||
{
|
||||
id: "caseStatus",
|
||||
key: "9",
|
||||
label: "api_test.definition.api_case_status",
|
||||
},
|
||||
{
|
||||
id: "casePassingRate",
|
||||
key: "a",
|
||||
label: "api_test.definition.api_case_passing_rate",
|
||||
},
|
||||
{ id: "status", key: "b", label: "api_test.definition.api_status" },
|
||||
{ id: "createTime", key: "c", label: "commons.create_time" },
|
||||
{ id: "description", key: "e", label: "commons.description" },
|
||||
],
|
||||
//接口用例
|
||||
API_CASE: [
|
||||
{id: 'num', key: '1', label: "ID"},
|
||||
{id: 'name', key: '2', label: 'test_track.case.name'},
|
||||
{id: 'priority', key: '3', label: 'test_track.case.priority'},
|
||||
{id: 'path', key: '4', label: 'api_test.definition.api_definition_path'},
|
||||
{id: 'execResult', key: '5', label: 'test_track.plan_view.execute_result'},
|
||||
{id: 'caseStatus', key: '6', label: 'commons.status'},
|
||||
{id: 'tags', key: '7', label: 'commons.tag'},
|
||||
{id: 'versionId', key: 'f', label: 'project.version.name', xpack: true},
|
||||
{id: 'createUser', key: '8', label: 'api_test.creator'},
|
||||
{id: 'updateTime', key: '9', label: 'api_test.definition.api_last_time'},
|
||||
{id: 'createTime', key: 'a', label: 'commons.create_time'},
|
||||
{id: 'passRate', key: 'b', label: 'commons.pass_rate'},
|
||||
{id: 'environment', key: 'e', label: 'commons.environment'},
|
||||
{ id: "num", key: "1", label: "ID" },
|
||||
{ id: "name", key: "2", label: "test_track.case.name" },
|
||||
{ id: "priority", key: "3", label: "test_track.case.priority" },
|
||||
{ id: "path", key: "4", label: "api_test.definition.api_definition_path" },
|
||||
{
|
||||
id: "execResult",
|
||||
key: "5",
|
||||
label: "test_track.plan_view.execute_result",
|
||||
},
|
||||
{ id: "caseStatus", key: "6", label: "commons.status" },
|
||||
{ id: "tags", key: "7", label: "commons.tag" },
|
||||
{ id: "versionId", key: "f", label: "project.version.name", xpack: true },
|
||||
{ id: "createUser", key: "8", label: "api_test.creator" },
|
||||
{ id: "updateTime", key: "9", label: "api_test.definition.api_last_time" },
|
||||
{ id: "createTime", key: "a", label: "commons.create_time" },
|
||||
{ id: "passRate", key: "b", label: "commons.pass_rate" },
|
||||
{ id: "environment", key: "e", label: "commons.environment" },
|
||||
],
|
||||
//场景测试
|
||||
API_SCENARIO: [
|
||||
{id: 'num', key: '1', label: "ID"},
|
||||
{id: 'name', key: '2', label: 'api_report.scenario_name'},
|
||||
{id: 'level', key: '3', label: 'api_test.automation.case_level'},
|
||||
{id: 'status', key: '4', label: 'test_track.plan.plan_status'},
|
||||
{id: 'tags', key: '5', label: 'commons.tag'},
|
||||
{id: 'versionId', key: 'f', label: 'project.version.name', xpack: true},
|
||||
{id: 'creatorName', key: 'd', label: 'api_test.automation.creator'},
|
||||
{id: 'principalName', key: '6', label: 'api_test.definition.api_principal'},
|
||||
{id: 'environmentMap', key: 'e', label: 'commons.environment'},
|
||||
{id: 'updateTime', key: '7', label: 'api_test.definition.api_last_time'},
|
||||
{id: 'stepTotal', key: '8', label: 'api_test.automation.step'},
|
||||
{id: 'lastResult', key: 'a', label: 'api_test.automation.last_result'},
|
||||
{id: 'passRate', key: 'b', label: 'api_test.automation.passing_rate'},
|
||||
{id: 'createTime', key: 'c', label: 'commons.create_time'},
|
||||
{ id: "num", key: "1", label: "ID" },
|
||||
{ id: "name", key: "2", label: "api_report.scenario_name" },
|
||||
{ id: "level", key: "3", label: "api_test.automation.case_level" },
|
||||
{ id: "status", key: "4", label: "test_track.plan.plan_status" },
|
||||
{ id: "tags", key: "5", label: "commons.tag" },
|
||||
{ id: "versionId", key: "f", label: "project.version.name", xpack: true },
|
||||
{ id: "creatorName", key: "d", label: "api_test.automation.creator" },
|
||||
{
|
||||
id: "principalName",
|
||||
key: "6",
|
||||
label: "api_test.definition.api_principal",
|
||||
},
|
||||
{ id: "environmentMap", key: "e", label: "commons.environment" },
|
||||
{ id: "updateTime", key: "7", label: "api_test.definition.api_last_time" },
|
||||
{ id: "stepTotal", key: "8", label: "api_test.automation.step" },
|
||||
{ id: "lastResult", key: "a", label: "api_test.automation.last_result" },
|
||||
{ id: "passRate", key: "b", label: "api_test.automation.passing_rate" },
|
||||
{ id: "createTime", key: "c", label: "commons.create_time" },
|
||||
{ id: "schedule", key: "g", label: "commons.trigger_mode.schedule" },
|
||||
],
|
||||
//场景测试
|
||||
UI_SCENARIO: [
|
||||
{id: 'num', key: '1', label: "ID"},
|
||||
{id: 'name', key: '2', label: 'api_report.scenario_name'},
|
||||
{id: 'level', key: '3', label: 'api_test.automation.case_level'},
|
||||
{id: 'status', key: '4', label: 'test_track.plan.plan_status'},
|
||||
{id: 'tags', key: '5', label: 'commons.tag'},
|
||||
{ id: "num", key: "1", label: "ID" },
|
||||
{ id: "name", key: "2", label: "api_report.scenario_name" },
|
||||
{ id: "level", key: "3", label: "api_test.automation.case_level" },
|
||||
{ id: "status", key: "4", label: "test_track.plan.plan_status" },
|
||||
{ id: "tags", key: "5", label: "commons.tag" },
|
||||
// {id: 'versionId', key: 'f', label: 'project.version.name', xpack: true},
|
||||
{id: 'creatorName', key: 'd', label: 'api_test.automation.creator'},
|
||||
{id: 'principalName', key: '6', label: 'api_test.definition.api_principal'},
|
||||
{id: 'environmentMap', key: 'e', label: 'commons.environment'},
|
||||
{id: 'updateTime', key: '7', label: 'api_test.definition.api_last_time'},
|
||||
{id: 'stepTotal', key: '8', label: 'api_test.automation.step'},
|
||||
{id: 'lastResult', key: 'a', label: 'api_test.automation.last_result'},
|
||||
{id: 'passRate', key: 'b', label: 'api_test.automation.passing_rate'},
|
||||
{id: 'createTime', key: 'c', label: 'commons.create_time'},
|
||||
{ id: "creatorName", key: "d", label: "api_test.automation.creator" },
|
||||
{
|
||||
id: "principalName",
|
||||
key: "6",
|
||||
label: "api_test.definition.api_principal",
|
||||
},
|
||||
{ id: "environmentMap", key: "e", label: "commons.environment" },
|
||||
{ id: "updateTime", key: "7", label: "api_test.definition.api_last_time" },
|
||||
{ id: "stepTotal", key: "8", label: "api_test.automation.step" },
|
||||
{ id: "lastResult", key: "a", label: "api_test.automation.last_result" },
|
||||
{ id: "passRate", key: "b", label: "api_test.automation.passing_rate" },
|
||||
{ id: "createTime", key: "c", label: "commons.create_time" },
|
||||
],
|
||||
//自定义指令
|
||||
UI_CUSTOM_COMMAND: [
|
||||
{id: 'num', key: '1', label: "ID"},
|
||||
{id: 'name', key: '2', label: 'ui.command_name_label'},
|
||||
{id: 'tags', key: '5', label: 'commons.tag'},
|
||||
{id: 'creatorName', key: 'd', label: 'api_test.automation.creator'},
|
||||
{id: 'principalName', key: '6', label: 'api_test.definition.api_principal'},
|
||||
{id: 'environmentMap', key: '8', label: 'commons.environment'},
|
||||
{id: 'updateTime', key: '7', label: 'api_test.definition.api_last_time'},
|
||||
{id: 'lastResult', key: 'a', label: 'ui.debug_result_label'},
|
||||
{id: 'createTime', key: 'c', label: 'commons.create_time'},
|
||||
{ id: "num", key: "1", label: "ID" },
|
||||
{ id: "name", key: "2", label: "ui.command_name_label" },
|
||||
{ id: "tags", key: "5", label: "commons.tag" },
|
||||
{ id: "creatorName", key: "d", label: "api_test.automation.creator" },
|
||||
{
|
||||
id: "principalName",
|
||||
key: "6",
|
||||
label: "api_test.definition.api_principal",
|
||||
},
|
||||
{ id: "environmentMap", key: "8", label: "commons.environment" },
|
||||
{ id: "updateTime", key: "7", label: "api_test.definition.api_last_time" },
|
||||
{ id: "lastResult", key: "a", label: "ui.debug_result_label" },
|
||||
{ id: "createTime", key: "c", label: "commons.create_time" },
|
||||
],
|
||||
// 测试报告
|
||||
TRACK_REPORT_TABLE: [
|
||||
{id: 'name', key: '1', label: 'test_track.report.list.name'},
|
||||
{id: 'testPlanName', key: '2', label: 'test_track.report.list.test_plan'},
|
||||
{id: 'creator', key: '3', label: 'test_track.report.list.creator'},
|
||||
{id: 'createTime', key: '4', label: 'test_track.report.list.create_time'},
|
||||
{id: 'triggerMode', key: '5', label: 'test_track.report.list.trigger_mode'},
|
||||
{id: 'status', key: '6', label: 'commons.status'},
|
||||
{id: 'runTime', key: '7', label: 'test_track.report.list.run_time'},
|
||||
{id: 'passRate', key: '8', label: 'test_track.report.list.pass_rate'},
|
||||
{ id: "name", key: "1", label: "test_track.report.list.name" },
|
||||
{ id: "testPlanName", key: "2", label: "test_track.report.list.test_plan" },
|
||||
{ id: "creator", key: "3", label: "test_track.report.list.creator" },
|
||||
{ id: "createTime", key: "4", label: "test_track.report.list.create_time" },
|
||||
{
|
||||
id: "triggerMode",
|
||||
key: "5",
|
||||
label: "test_track.report.list.trigger_mode",
|
||||
},
|
||||
{ id: "status", key: "6", label: "commons.status" },
|
||||
{ id: "runTime", key: "7", label: "test_track.report.list.run_time" },
|
||||
{ id: "passRate", key: "8", label: "test_track.report.list.pass_rate" },
|
||||
],
|
||||
|
||||
// 场景变量
|
||||
VARIABLE_LIST_TABLE: [
|
||||
{id: 'num', key: '1', label: "ID"},
|
||||
{id: 'name', key: '2', label: 'api_test.variable_name'},
|
||||
{id: 'type', key: '3', label: 'test_track.case.type'},
|
||||
{id: 'value', key: '4', label: 'api_test.value'},
|
||||
{id: 'description', key: '5', label: 'commons.description'},
|
||||
{ id: "num", key: "1", label: "ID" },
|
||||
{ id: "name", key: "2", label: "api_test.variable_name" },
|
||||
{ id: "type", key: "3", label: "test_track.case.type" },
|
||||
{ id: "value", key: "4", label: "api_test.value" },
|
||||
{ id: "description", key: "5", label: "commons.description" },
|
||||
],
|
||||
|
||||
//缺陷列表
|
||||
ELEMENT_LIST: [
|
||||
{id: 'num', key: '1', label: 'ID'},
|
||||
{id: 'name', key: '2', label: '元素名称'},
|
||||
{id: 'locationType', key: '3', label: '定位类型'},
|
||||
{id: 'location', key: '4', label: '元素定位'},
|
||||
{id: 'createUser', key: '5', label: '创建人'},
|
||||
{id: 'createTime', key: '6', label: 'commons.create_time'},
|
||||
{id: 'updateUser', key: '7', label: '更新人'},
|
||||
{id: 'updateTime', key: '8', label: 'commons.update_time'},
|
||||
{ id: "num", key: "1", label: "ID" },
|
||||
{ id: "name", key: "2", label: "元素名称" },
|
||||
{ id: "locationType", key: "3", label: "定位类型" },
|
||||
{ id: "location", key: "4", label: "元素定位" },
|
||||
{ id: "createUser", key: "5", label: "创建人" },
|
||||
{ id: "createTime", key: "6", label: "commons.create_time" },
|
||||
{ id: "updateUser", key: "7", label: "更新人" },
|
||||
{ id: "updateTime", key: "8", label: "commons.update_time" },
|
||||
],
|
||||
|
||||
//空间配额
|
||||
QUOTA_WS_LIST: [
|
||||
{id: 'workspaceName', key: 'a', label: 'commons.workspace'},
|
||||
{id: 'api', key: 'b', label: 'quota.api'},
|
||||
{id: 'performance', key: 'c', label: 'quota.performance'},
|
||||
{id: 'maxThreads', key: 'd', label: 'quota.max_threads'},
|
||||
{id: 'duration', key: 'e', label: 'quota.duration'},
|
||||
{id: 'resourcePool', key: 'f', label: 'quota.resource_pool'},
|
||||
{id: 'useDefault', key: 'j', label: 'quota.use_default'},
|
||||
{id: 'vumTotal', key: 'h', label: 'quota.vum_total'},
|
||||
{id: 'vumUsed', key: 'i', label: 'quota.vum_used'},
|
||||
{id: 'member', key: 'g', label: 'quota.member'},
|
||||
{id: 'project', key: 'k', label: 'quota.project'},
|
||||
{ id: "workspaceName", key: "a", label: "commons.workspace" },
|
||||
{ id: "api", key: "b", label: "quota.api" },
|
||||
{ id: "performance", key: "c", label: "quota.performance" },
|
||||
{ id: "maxThreads", key: "d", label: "quota.max_threads" },
|
||||
{ id: "duration", key: "e", label: "quota.duration" },
|
||||
{ id: "resourcePool", key: "f", label: "quota.resource_pool" },
|
||||
{ id: "useDefault", key: "j", label: "quota.use_default" },
|
||||
{ id: "vumTotal", key: "h", label: "quota.vum_total" },
|
||||
{ id: "vumUsed", key: "i", label: "quota.vum_used" },
|
||||
{ id: "member", key: "g", label: "quota.member" },
|
||||
{ id: "project", key: "k", label: "quota.project" },
|
||||
],
|
||||
|
||||
//项目配额
|
||||
QUOTA_PJ_LIST: [
|
||||
{id: 'projectName', key: 'a', label: 'commons.project'},
|
||||
{id: 'api', key: 'b', label: 'quota.api'},
|
||||
{id: 'performance', key: 'c', label: 'quota.performance'},
|
||||
{id: 'maxThreads', key: 'd', label: 'quota.max_threads'},
|
||||
{id: 'duration', key: 'e', label: 'quota.duration'},
|
||||
{id: 'resourcePool', key: 'f', label: 'quota.resource_pool'},
|
||||
{id: 'useDefault', key: 'j', label: 'quota.use_default'},
|
||||
{id: 'vumTotal', key: 'h', label: 'quota.vum_total'},
|
||||
{id: 'vumUsed', key: 'i', label: 'quota.vum_used'},
|
||||
{id: 'member', key: 'g', label: 'quota.member'},
|
||||
{ id: "projectName", key: "a", label: "commons.project" },
|
||||
{ id: "api", key: "b", label: "quota.api" },
|
||||
{ id: "performance", key: "c", label: "quota.performance" },
|
||||
{ id: "maxThreads", key: "d", label: "quota.max_threads" },
|
||||
{ id: "duration", key: "e", label: "quota.duration" },
|
||||
{ id: "resourcePool", key: "f", label: "quota.resource_pool" },
|
||||
{ id: "useDefault", key: "j", label: "quota.use_default" },
|
||||
{ id: "vumTotal", key: "h", label: "quota.vum_total" },
|
||||
{ id: "vumUsed", key: "i", label: "quota.vum_used" },
|
||||
{ id: "member", key: "g", label: "quota.member" },
|
||||
],
|
||||
|
||||
// 测试报告列表
|
||||
PERFORMANCE_REPORT_TABLE: [
|
||||
{id: 'testName', key: 'a', label: 'report.test_name'},
|
||||
{id: 'name', key: 'b', label: 'commons.name'},
|
||||
{id: 'versionId', key: 'c', label: 'project.version.name'},
|
||||
{id: 'userName', key: 'd', label: 'report.user_name'},
|
||||
{id: 'maxUsers', key: 'e', label: 'report.max_users'},
|
||||
{id: 'avgResponseTime', key: 'f', label: 'report.response_time'},
|
||||
{id: 'tps', key: 'g', label: 'TPS'},
|
||||
{id: 'testStartTime', key: 'h', label: 'report.test_start_time'},
|
||||
{id: 'testEndTime', key: 'i', label: 'report.test_end_time'},
|
||||
{id: 'testDuration', key: 'j', label: 'report.test_execute_time'},
|
||||
{id: 'triggerMode', key: 'k', label: 'test_track.report.list.trigger_mode'},
|
||||
{id: 'status', key: 'l', label: 'commons.status'},
|
||||
]
|
||||
|
||||
}
|
||||
{ id: "testName", key: "a", label: "report.test_name" },
|
||||
{ id: "name", key: "b", label: "commons.name" },
|
||||
{ id: "versionId", key: "c", label: "project.version.name" },
|
||||
{ id: "userName", key: "d", label: "report.user_name" },
|
||||
{ id: "maxUsers", key: "e", label: "report.max_users" },
|
||||
{ id: "avgResponseTime", key: "f", label: "report.response_time" },
|
||||
{ id: "tps", key: "g", label: "TPS" },
|
||||
{ id: "testStartTime", key: "h", label: "report.test_start_time" },
|
||||
{ id: "testEndTime", key: "i", label: "report.test_end_time" },
|
||||
{ id: "testDuration", key: "j", label: "report.test_execute_time" },
|
||||
{
|
||||
id: "triggerMode",
|
||||
key: "k",
|
||||
label: "test_track.report.list.trigger_mode",
|
||||
},
|
||||
{ id: "status", key: "l", label: "commons.status" },
|
||||
],
|
||||
};
|
||||
|
|
|
@ -73,7 +73,6 @@ public class TestPlanReportDataStruct extends TestPlanReportContent {
|
|||
List<TestPlanApiDTO> runningCaseList =
|
||||
apiAllCases.stream().filter(
|
||||
dto -> StringUtils.equalsAnyIgnoreCase(dto.getExecResult(),
|
||||
ApiReportStatus.PENDING.name(),
|
||||
ApiReportStatus.RERUNNING.name(),
|
||||
ApiReportStatus.RUNNING.name())).toList();
|
||||
if (runningCaseList.size() > 0) {
|
||||
|
@ -84,7 +83,6 @@ public class TestPlanReportDataStruct extends TestPlanReportContent {
|
|||
List<TestPlanScenarioDTO> runningCaseList =
|
||||
scenarioAllCases.stream().filter(
|
||||
dto -> StringUtils.equalsAnyIgnoreCase(dto.getLastResult(),
|
||||
ApiReportStatus.PENDING.name(),
|
||||
ApiReportStatus.RERUNNING.name(),
|
||||
ApiReportStatus.RUNNING.name())).toList();
|
||||
if (runningCaseList.size() > 0) {
|
||||
|
@ -95,8 +93,6 @@ public class TestPlanReportDataStruct extends TestPlanReportContent {
|
|||
List<TestPlanLoadCaseDTO> runningCaseList =
|
||||
loadAllCases.stream().filter(
|
||||
dto -> StringUtils.equalsAnyIgnoreCase(dto.getStatus(),
|
||||
PerformanceTestStatus.Starting.name(),
|
||||
PerformanceTestStatus.Running.name(),
|
||||
PerformanceTestStatus.Reporting.name())).toList();
|
||||
if (runningCaseList.size() > 0) {
|
||||
return true;
|
||||
|
@ -106,7 +102,6 @@ public class TestPlanReportDataStruct extends TestPlanReportContent {
|
|||
List<TestPlanUiScenarioDTO> runningCaseList =
|
||||
uiAllCases.stream().filter(
|
||||
dto -> StringUtils.equalsAnyIgnoreCase(dto.getLastResult(),
|
||||
ApiReportStatus.PENDING.name(),
|
||||
ApiReportStatus.RERUNNING.name(),
|
||||
ApiReportStatus.RUNNING.name())).toList();
|
||||
if (runningCaseList.size() > 0) {
|
||||
|
|
|
@ -2408,7 +2408,9 @@ public class TestPlanService {
|
|||
TestPlanReportDataStruct testPlanReportDataStruct = new TestPlanReportDataStruct();
|
||||
try {
|
||||
testPlanReportDataStruct = this.generateReportStruct(testPlanWithBLOBs, testPlanReport, testPlanReportContent, false);
|
||||
if (StringUtils.isBlank(testPlanReportContent.getApiBaseCount()) && !testPlanReportDataStruct.hasRunningCase()) {
|
||||
if (StringUtils.isBlank(testPlanReportContent.getApiBaseCount())
|
||||
&& !testPlanReportDataStruct.hasRunningCase()
|
||||
&& StringUtils.equalsAnyIgnoreCase(testPlanReport.getStatus(), TestPlanReportStatus.FAILED.name(), TestPlanReportStatus.COMPLETED.name(), TestPlanReportStatus.SUCCESS.name())) {
|
||||
//旧版本的测试计划报告,没有重新统计过测试计划报告时,且当不存在运行中的用例,会将结果保存下来
|
||||
testPlanReportService.updateReportStructInfo(testPlanReportContent, testPlanReportDataStruct);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue