Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
a722d6419e
|
@ -32,4 +32,4 @@ target
|
|||
.project
|
||||
.classpath
|
||||
.factorypath
|
||||
*.jar
|
||||
src/main/resources/jmeter/lib/
|
|
@ -15,4 +15,5 @@ public class Scenario {
|
|||
private List<KeyValue> headers;
|
||||
private List<Request> requests;
|
||||
private DubboConfig dubboConfig;
|
||||
private Boolean enable;
|
||||
}
|
||||
|
|
|
@ -49,4 +49,6 @@ public class DubboRequest implements Request {
|
|||
private BeanShellPreProcessor beanShellPreProcessor;
|
||||
@JSONField(ordinal = 13)
|
||||
private BeanShellPostProcessor beanShellPostProcessor;
|
||||
@JSONField(ordinal = 14)
|
||||
private Boolean enable;
|
||||
}
|
||||
|
|
|
@ -41,4 +41,10 @@ public class HttpRequest implements Request {
|
|||
private BeanShellPreProcessor beanShellPreProcessor;
|
||||
@JSONField(ordinal = 12)
|
||||
private BeanShellPostProcessor beanShellPostProcessor;
|
||||
@JSONField(ordinal = 13)
|
||||
private Boolean enable;
|
||||
@JSONField(ordinal = 14)
|
||||
private Integer connectTimeout;
|
||||
@JSONField(ordinal = 15)
|
||||
private Integer responseTimeout;
|
||||
}
|
||||
|
|
|
@ -149,9 +149,12 @@ public class JmeterDocumentParser {
|
|||
String path = ele.getTextContent();
|
||||
Map<String, String> parser = parserUrl(path);
|
||||
String url = parser.get("URL");
|
||||
String params = parser.keySet().stream().filter(k -> !"URL".equals(k)).reduce("", (u, k) -> {
|
||||
String params = parser.keySet().stream().filter(k -> !"URL".equals(k)).reduce("?", (u, k) -> {
|
||||
String v = parser.get(k);
|
||||
u += "&" + k + "=" + ScriptEngineUtils.calculate(v);
|
||||
if (!StringUtils.equals("?", u)) {
|
||||
u += "&";
|
||||
}
|
||||
u += k + "=" + ScriptEngineUtils.calculate(v);
|
||||
return u;
|
||||
});
|
||||
ele.setTextContent(url + params);
|
||||
|
|
|
@ -18,15 +18,13 @@ import io.metersphere.commons.constants.FileType;
|
|||
import io.metersphere.commons.constants.ScheduleGroup;
|
||||
import io.metersphere.commons.constants.ScheduleType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.job.sechedule.ApiTestJob;
|
||||
import io.metersphere.service.FileService;
|
||||
import io.metersphere.service.QuotaService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
import org.apache.dubbo.common.URL;
|
||||
|
@ -37,6 +35,7 @@ import org.springframework.util.CollectionUtils;
|
|||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -92,6 +91,7 @@ public class APITestService {
|
|||
}
|
||||
|
||||
public void copy(SaveAPITestRequest request) {
|
||||
checkQuota();
|
||||
request.setName(request.getName() + " Copy");
|
||||
try {
|
||||
checkNameExist(request);
|
||||
|
@ -355,4 +355,11 @@ public class APITestService {
|
|||
jMeterService.run(request.getId(), reportId, is);
|
||||
return reportId;
|
||||
}
|
||||
|
||||
private void checkQuota() {
|
||||
QuotaService quotaService = CommonBeanFactory.getBean(QuotaService.class);
|
||||
if (quotaService != null) {
|
||||
quotaService.checkAPIQuota();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
</select>
|
||||
|
||||
<select id="list" resultType="io.metersphere.track.dto.TestPlanCaseDTO">
|
||||
select test_plan_test_case.*, test_case.*,test_case_node.name as model
|
||||
select test_case.remark, test_plan_test_case.*,test_case.*,test_case_node.name as model
|
||||
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
|
||||
|
|
|
@ -16,11 +16,19 @@ public class CommonBeanFactory implements ApplicationContextAware {
|
|||
}
|
||||
|
||||
public static Object getBean(String beanName) {
|
||||
try {
|
||||
return context != null && !StringUtils.isBlank(beanName) ? context.getBean(beanName) : null;
|
||||
} catch (BeansException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T getBean(Class<T> className) {
|
||||
try {
|
||||
return context != null && className != null ? context.getBean(className) : null;
|
||||
} catch (BeansException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
public interface QuotaService {
|
||||
|
||||
void checkAPIQuota();
|
||||
}
|
|
@ -235,7 +235,7 @@ public class IssuesService {
|
|||
" \"key\":\"" + jiraKey + "\"\n" +
|
||||
" },\n" +
|
||||
" \"summary\":\"" + issuesRequest.getTitle() + "\",\n" +
|
||||
" \"description\":\"" + issuesRequest.getContent() + "\",\n" +
|
||||
" \"description\": " + JSON.toJSONString(issuesRequest.getContent()) + ",\n" +
|
||||
" \"issuetype\":{\n" +
|
||||
" \"id\":\"10009\",\n" +
|
||||
" \"name\":\"Defect\"\n" +
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package io.metersphere.track.service;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseIssues;
|
||||
import io.metersphere.base.domain.TestCaseIssuesExample;
|
||||
import io.metersphere.base.mapper.IssuesMapper;
|
||||
import io.metersphere.base.mapper.TestCaseIssuesMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestCaseIssueService {
|
||||
|
||||
@Resource
|
||||
private TestCaseIssuesMapper testCaseIssuesMapper;
|
||||
@Resource
|
||||
private IssuesMapper issuesMapper;
|
||||
|
||||
public void delTestCaseIssues(String testCaseId) {
|
||||
TestCaseIssuesExample example = new TestCaseIssuesExample();
|
||||
example.createCriteria().andTestCaseIdEqualTo(testCaseId);
|
||||
List<TestCaseIssues> testCaseIssues = testCaseIssuesMapper.selectByExample(example);
|
||||
if (!CollectionUtils.isEmpty(testCaseIssues)) {
|
||||
List<String> list = testCaseIssues.stream().map(TestCaseIssues::getIssuesId).collect(Collectors.toList());
|
||||
list.forEach(id -> {
|
||||
issuesMapper.deleteByPrimaryKey(id);
|
||||
});
|
||||
}
|
||||
testCaseIssuesMapper.deleteByExample(example);
|
||||
}
|
||||
}
|
|
@ -73,6 +73,9 @@ public class TestCaseService {
|
|||
@Resource
|
||||
UserRoleMapper userRoleMapper;
|
||||
|
||||
@Resource
|
||||
TestCaseIssueService testCaseIssueService;
|
||||
|
||||
public void addTestCase(TestCaseWithBLOBs testCase) {
|
||||
testCase.setName(testCase.getName());
|
||||
checkTestCaseExist(testCase);
|
||||
|
@ -149,6 +152,7 @@ public class TestCaseService {
|
|||
TestPlanTestCaseExample example = new TestPlanTestCaseExample();
|
||||
example.createCriteria().andCaseIdEqualTo(testCaseId);
|
||||
testPlanTestCaseMapper.deleteByExample(example);
|
||||
testCaseIssueService.delTestCaseIssues(testCaseId);
|
||||
return testCaseMapper.deleteByPrimaryKey(testCaseId);
|
||||
}
|
||||
|
||||
|
@ -426,6 +430,7 @@ public class TestCaseService {
|
|||
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, request);
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
testCaseMapper.updateByExampleSelective(
|
||||
testCase,
|
||||
testCaseExample);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8eff343619df1572e1cded52f173257ef4b518a1
|
||||
Subproject commit b86032cbbda9a9e6028308aa95a887cff2192f1c
|
|
@ -142,3 +142,5 @@ quota_workspace_excess_org_performance=The total number of performance tests for
|
|||
quota_workspace_excess_org_max_threads=The maximum concurrent number of workspaces cannot exceed the quota of the organization
|
||||
quota_workspace_excess_org_max_duration=The stress test duration of the workspace cannot exceed the organization's quota
|
||||
quota_workspace_excess_org_resource_pool=The resource pool of the workspace cannot exceed the resource pool of the organization
|
||||
quota_api_excess_workspace=The number of interface tests exceeds the workspace quota
|
||||
quota_api_excess_organization=The number of interface tests exceeds the organization quota
|
|
@ -142,6 +142,8 @@ quota_workspace_excess_org_performance=工作空间的性能测试数量总和
|
|||
quota_workspace_excess_org_max_threads=工作空间的最大并发数不能超过组织的配额
|
||||
quota_workspace_excess_org_max_duration=工作空间的压测时长不能超过组织的配额
|
||||
quota_workspace_excess_org_resource_pool=工作空间的资源池不能超过组织的资源池范围
|
||||
quota_api_excess_workspace=接口测试数量超过工作空间限额
|
||||
quota_api_excess_organization=接口测试数量超过组织限额
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -142,3 +142,5 @@ quota_workspace_excess_org_performance=工作空間的性能測試數量總和
|
|||
quota_workspace_excess_org_max_threads=工作空間的最大並發數不能超過組織的配額
|
||||
quota_workspace_excess_org_max_duration=工作空間的壓測時長不能超過組織的配額
|
||||
quota_workspace_excess_org_resource_pool=工作空間的資源池不能超過組織的資源池範圍
|
||||
quota_api_excess_workspace=接口測試數量超過工作空間限額
|
||||
quota_api_excess_organization=接口測試數量超過組織限額
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']" index="3">
|
||||
<template v-slot:title>{{ $t('commons.project') }}</template>
|
||||
<ms-recent-list :options="projectRecent"/>
|
||||
<ms-recent-list ref="projectRecent" :options="projectRecent"/>
|
||||
<el-divider class="menu-divider"/>
|
||||
<ms-show-all :index="'/api/project/all'"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/api/project/create'"
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']" index="4">
|
||||
<template v-slot:title>{{ $t('commons.test') }}</template>
|
||||
<ms-recent-list :options="testRecent"/>
|
||||
<ms-recent-list ref="testRecent" :options="testRecent"/>
|
||||
<el-divider class="menu-divider"/>
|
||||
<ms-show-all :index="'/api/test/list/all'"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/api/test/create'"
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']" index="5">
|
||||
<template v-slot:title>{{ $t('commons.report') }}</template>
|
||||
<ms-recent-list :options="reportRecent"/>
|
||||
<ms-recent-list ref="reportRecent" :options="reportRecent"/>
|
||||
<el-divider class="menu-divider"/>
|
||||
<ms-show-all :index="'/api/report/list/all'"/>
|
||||
</el-submenu>
|
||||
|
@ -50,6 +50,7 @@
|
|||
import MsShowAll from "../../common/head/ShowAll";
|
||||
import MsCreateButton from "../../common/head/CreateButton";
|
||||
import MsCreateTest from "../../common/head/CreateTest";
|
||||
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "MsApiHeaderMenus",
|
||||
|
@ -85,6 +86,13 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
ApiEvent.$on(LIST_CHANGE, () => {
|
||||
this.$refs.projectRecent.recent();
|
||||
this.$refs.testRecent.recent();
|
||||
this.$refs.reportRecent.recent();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem";
|
||||
import {REPORT_CONFIGS} from "../../common/components/search/search-components";
|
||||
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -127,6 +128,8 @@
|
|||
this.result = this.$post("/api/report/delete", {id: report.id}, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.search();
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
ApiEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,9 +68,9 @@
|
|||
</el-tabs>
|
||||
<div v-else>
|
||||
<ms-request-metric :request="request"/>
|
||||
<ms-request-text :request="request"/>
|
||||
<ms-request-text v-if="isCodeEditAlive" :request="request"/>
|
||||
<br>
|
||||
<ms-response-text :response="request.responseResult"/>
|
||||
<ms-response-text v-if="isCodeEditAlive" :response="request.responseResult"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
|
@ -96,12 +96,17 @@
|
|||
return {
|
||||
isActive: true,
|
||||
activeName: "sub",
|
||||
isCodeEditAlive: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
active() {
|
||||
this.isActive = !this.isActive;
|
||||
},
|
||||
reload() {
|
||||
this.isCodeEditAlive = false;
|
||||
this.$nextTick(() => (this.isCodeEditAlive = true));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -111,7 +116,7 @@
|
|||
},
|
||||
hasSub() {
|
||||
return this.request.subRequestResults.length > 0;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
import MsTableOperators from "../../common/components/MsTableOperators";
|
||||
import {_filter, _sort} from "@/common/js/utils";
|
||||
import {TEST_CONFIGS} from "../../common/components/search/search-components";
|
||||
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -183,6 +184,8 @@
|
|||
this.result = this.$post("/api/delete", {id: test.id}, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.search();
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
ApiEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form :model="request" ref="request" label-width="100px">
|
||||
|
||||
<el-form-item :label="$t('api_test.request.connect_timeout')" prop="connectTimeout">
|
||||
<el-input-number size="small" :disabled="isReadOnly" v-model="request.connectTimeout" :placeholder="$t('commons.millisecond')" :maxlength="1000*10000000" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.request.response_timeout')" prop="responseTimeout">
|
||||
<el-input-number size="small" :disabled="isReadOnly" v-model="request.responseTimeout" :placeholder="$t('commons.millisecond')" :maxlength="1000*10000000"/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsApiAdvancedConfig",
|
||||
props: {
|
||||
request: Object,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -5,7 +5,7 @@
|
|||
<ms-api-collapse v-model="activeName" @change="handleChange" accordion>
|
||||
<draggable :list="scenarios" group="Scenario" class="scenario-draggable" ghost-class="scenario-ghost">
|
||||
<ms-api-collapse-item v-for="(scenario, index) in scenarios" :key="index"
|
||||
:title="scenario.name" :name="index">
|
||||
:title="scenario.name" :name="index" :class="{'disable-scenario': !scenario.enable}">
|
||||
<template slot="title">
|
||||
<div class="scenario-name">
|
||||
{{scenario.name}}
|
||||
|
@ -22,6 +22,12 @@
|
|||
<el-dropdown-item :disabled="isReadOnly" :command="{type:'delete', index:index}">
|
||||
{{$t('api_test.scenario.delete')}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="scenario.enable" :disabled="isReadOnly" :command="{type:'disable', index:index}">
|
||||
{{$t('api_test.scenario.disable')}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="!scenario.enable" :disabled="isReadOnly" :command="{type:'enable', index:index}">
|
||||
{{$t('api_test.scenario.enable')}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
@ -108,6 +114,12 @@ export default {
|
|||
this.select(this.scenarios[0]);
|
||||
}
|
||||
},
|
||||
disableScenario: function (index) {
|
||||
this.scenarios[index].enable = false;
|
||||
},
|
||||
enableScenario: function (index) {
|
||||
this.scenarios[index].enable = true;
|
||||
},
|
||||
handleChange: function (index) {
|
||||
this.select(this.scenarios[index]);
|
||||
},
|
||||
|
@ -119,6 +131,12 @@ export default {
|
|||
case "delete":
|
||||
this.deleteScenario(command.index);
|
||||
break;
|
||||
case "disable":
|
||||
this.disableScenario(command.index);
|
||||
break;
|
||||
case "enable":
|
||||
this.enableScenario(command.index);
|
||||
break;
|
||||
}
|
||||
},
|
||||
select: function (obj, scenario) {
|
||||
|
@ -203,9 +221,9 @@ export default {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.scenario-name > #hint {
|
||||
color: #8a8b8d;
|
||||
}
|
||||
/*.scenario-name > #hint {*/
|
||||
/*color: #8a8b8d;*/
|
||||
/*}*/
|
||||
|
||||
.scenario-btn {
|
||||
text-align: center;
|
||||
|
@ -241,4 +259,9 @@ export default {
|
|||
.scenario-draggable {
|
||||
background-color: #909399;
|
||||
}
|
||||
|
||||
.disable-scenario >>> .el-collapse-item__header {
|
||||
border-right: 2px solid #909399;
|
||||
color: #8a8b8d;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -113,6 +113,7 @@
|
|||
<style scoped>
|
||||
.el-collapse-item__header {
|
||||
padding-left: 7px;
|
||||
border-right: 2px solid #409eff;
|
||||
}
|
||||
|
||||
.el-collapse-item__header.is-active {
|
||||
|
@ -122,4 +123,5 @@
|
|||
.el-collapse-item__content {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-button class="debug-button" size="small" type="primary" @click="runDebug">{{$t('load_test.save_and_run')}}</el-button>
|
||||
<el-button :disabled="!request.enable || !scenario.enable || isReadOnly" class="debug-button" size="small" type="primary" @click="runDebug">{{$t('load_test.save_and_run')}}</el-button>
|
||||
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="Interface" name="interface">
|
||||
|
@ -58,7 +58,7 @@
|
|||
import MsApiKeyValue from "../ApiKeyValue";
|
||||
import MsApiBody from "../ApiBody";
|
||||
import MsApiAssertions from "../assertion/ApiAssertions";
|
||||
import {DubboRequest} from "../../model/ScenarioModel";
|
||||
import {DubboRequest, Scenario} from "../../model/ScenarioModel";
|
||||
import MsApiExtract from "../extract/ApiExtract";
|
||||
import ApiRequestMethodSelect from "../collapse/ApiRequestMethodSelect";
|
||||
import MsDubboInterface from "@/business/components/api/test/components/request/dubbo/Interface";
|
||||
|
@ -78,6 +78,7 @@
|
|||
},
|
||||
props: {
|
||||
request: DubboRequest,
|
||||
scenario: Scenario,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
|
|
@ -40,8 +40,7 @@
|
|||
</el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-button class="debug-button" size="small" type="primary" @click="runDebug">{{ $t('load_test.save_and_run') }}
|
||||
</el-button>
|
||||
<el-button :disabled="!request.enable || !scenario.enable || isReadOnly" class="debug-button" size="small" type="primary" @click="runDebug">{{ $t('load_test.save_and_run') }}</el-button>
|
||||
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
||||
|
@ -74,6 +73,9 @@
|
|||
<el-tab-pane :label="$t('api_test.request.processor.post_exec_script')" name="beanShellPostProcessor">
|
||||
<ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPostProcessor"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.request.timeout_config')" name="advancedConfig">
|
||||
<ms-api-advanced-config :is-read-only="isReadOnly" :request="request"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
</template>
|
||||
|
@ -88,10 +90,12 @@ import ApiRequestMethodSelect from "../collapse/ApiRequestMethodSelect";
|
|||
import {REQUEST_HEADERS} from "@/common/js/constants";
|
||||
import MsApiVariable from "@/business/components/api/test/components/ApiVariable";
|
||||
import MsBeanShellProcessor from "../processor/BeanShellProcessor";
|
||||
import MsApiAdvancedConfig from "../ApiAdvancedConfig";
|
||||
|
||||
export default {
|
||||
name: "MsApiHttpRequestForm",
|
||||
components: {
|
||||
MsApiAdvancedConfig,
|
||||
MsBeanShellProcessor,
|
||||
MsApiVariable, ApiRequestMethodSelect, MsApiExtract, MsApiAssertions, MsApiBody, MsApiKeyValue},
|
||||
props: {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="request-container">
|
||||
<draggable :list="this.scenario.requests" group="Request" class="request-draggable" ghost-class="request-ghost">
|
||||
<div class="request-item" v-for="(request, index) in this.scenario.requests" :key="index" @click="select(request)"
|
||||
:class="{'selected': isSelected(request)}">
|
||||
:class="{'selected': isSelected(request), 'disable-request': !request.enable || !scenario.enable}">
|
||||
<el-row type="flex" align="middle">
|
||||
<div class="request-type">
|
||||
{{request.showType()}}
|
||||
|
@ -23,6 +23,12 @@
|
|||
<el-dropdown-item :disabled="isReadOnly" :command="{type: 'delete', index: index}">
|
||||
{{$t('api_test.request.delete')}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="request.enable" :disabled="isReadOnly" :command="{type: 'disable', index: index}">
|
||||
{{$t('api_test.scenario.disable')}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="!request.enable" :disabled="isReadOnly" :command="{type: 'enable', index: index}">
|
||||
{{$t('api_test.scenario.enable')}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
@ -70,7 +76,7 @@
|
|||
computed: {
|
||||
isSelected() {
|
||||
return function (request) {
|
||||
return this.selected.id === request.id;
|
||||
return this.selected === request;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -89,6 +95,12 @@
|
|||
let request = this.scenario.requests[index];
|
||||
this.scenario.requests.push(new RequestFactory(request));
|
||||
},
|
||||
disableRequest: function (index) {
|
||||
this.scenario.requests[index].enable = false;
|
||||
},
|
||||
enableRequest: function (index) {
|
||||
this.scenario.requests[index].enable = true;
|
||||
},
|
||||
deleteRequest: function (index) {
|
||||
this.scenario.requests.splice(index, 1);
|
||||
if (this.scenario.requests.length === 0) {
|
||||
|
@ -103,6 +115,12 @@
|
|||
case "delete":
|
||||
this.deleteRequest(command.index);
|
||||
break;
|
||||
case "disable":
|
||||
this.disableRequest(command.index);
|
||||
break;
|
||||
case "enable":
|
||||
this.enableRequest(command.index);
|
||||
break;
|
||||
}
|
||||
},
|
||||
select: function (request) {
|
||||
|
@ -186,4 +204,17 @@
|
|||
opacity: 0.5;
|
||||
background-color: #909399;
|
||||
}
|
||||
|
||||
.request-item.disable-request {
|
||||
border-left-color: #909399;
|
||||
}
|
||||
|
||||
.disable-request .request-type {
|
||||
background-color: #909399;
|
||||
}
|
||||
|
||||
.disable-request .request-method {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<template>
|
||||
<div class="request-form">
|
||||
<component @runDebug="runDebug" :is="component" :is-read-only="isReadOnly" :request="request" :scenario="scenario"/>
|
||||
<ms-request-result-tail v-loading="debugReportLoading" v-if="isCompleted" :request="request.debugRequestResult ? request.debugRequestResult : {responseResult: {}, subRequestResults: []}" :scenario-name="request.debugScenario ? request.debugScenario.name : ''"/>
|
||||
<ms-request-result-tail v-loading="debugReportLoading" v-if="isCompleted" :request="request.debugRequestResult ? request.debugRequestResult : {responseResult: {}, subRequestResults: []}"
|
||||
:scenario-name="request.debugScenario ? request.debugScenario.name : ''" ref="msDebugResult"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -72,9 +73,15 @@ export default {
|
|||
if (res) {
|
||||
this.debugReportLoading = false;
|
||||
this.request.debugReport = res;
|
||||
if (res.scenarios && res.scenarios.length > 0) {
|
||||
this.request.debugScenario = res.scenarios[0];
|
||||
this.request.debugRequestResult = this.request.debugScenario.requestResults[0];
|
||||
this.deleteReport(this.debugReportId)
|
||||
this.deleteReport(this.debugReportId);
|
||||
} else {
|
||||
this.request.debugScenario = new Scenario();
|
||||
this.request.debugRequestResult = {responseResult: {}, subRequestResults: []};
|
||||
}
|
||||
this.$refs.msDebugResult.reload();
|
||||
} else {
|
||||
setTimeout(this.getReport, 2000)
|
||||
}
|
||||
|
|
|
@ -289,6 +289,12 @@ export class HTTPSamplerProxy extends DefaultTestElement {
|
|||
} else {
|
||||
this.stringProp("HTTPSampler.port", options.port);
|
||||
}
|
||||
if (options.connectTimeout) {
|
||||
this.stringProp('HTTPSampler.connect_timeout', options.connectTimeout);
|
||||
}
|
||||
if (options.responseTimeout) {
|
||||
this.stringProp('HTTPSampler.response_timeout', options.responseTimeout);
|
||||
}
|
||||
|
||||
this.boolProp("HTTPSampler.follow_redirects", options.follow, true);
|
||||
this.boolProp("HTTPSampler.use_keepalive", options.keepalive, true);
|
||||
|
|
|
@ -207,6 +207,7 @@ export class Scenario extends BaseConfig {
|
|||
this.dubboConfig = undefined;
|
||||
this.environment = undefined;
|
||||
this.enableCookieShare = false;
|
||||
this.enable = true;
|
||||
|
||||
this.set(options);
|
||||
this.sets({variables: KeyValue, headers: KeyValue, requests: RequestFactory}, options);
|
||||
|
@ -304,6 +305,9 @@ export class HttpRequest extends Request {
|
|||
this.debugReport = undefined;
|
||||
this.beanShellPreProcessor = undefined;
|
||||
this.beanShellPostProcessor = undefined;
|
||||
this.enable = true;
|
||||
this.connectTimeout = 60*1000;
|
||||
this.responseTimeout = undefined;
|
||||
|
||||
this.set(options);
|
||||
this.sets({parameters: KeyValue, headers: KeyValue}, options);
|
||||
|
@ -383,6 +387,7 @@ export class DubboRequest extends Request {
|
|||
this.debugReport = undefined;
|
||||
this.beanShellPreProcessor = new BeanShellProcessor(options.beanShellPreProcessor);
|
||||
this.beanShellPostProcessor = new BeanShellProcessor(options.beanShellPostProcessor);
|
||||
this.enable = true;
|
||||
|
||||
this.sets({args: KeyValue, attachmentArgs: KeyValue}, options);
|
||||
}
|
||||
|
@ -723,6 +728,9 @@ class JMXHttpRequest {
|
|||
let url = new URL(environment.protocol + "://" + environment.socket);
|
||||
this.path = this.getPostQueryParameters(request, decodeURIComponent(url.pathname + (request.path ? request.path : '')));
|
||||
}
|
||||
this.connectTimeout = request.connectTimeout;
|
||||
this.responseTimeout = request.responseTimeout;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -807,6 +815,8 @@ class JMXGenerator {
|
|||
|
||||
addScenarios(testPlan, scenarios) {
|
||||
scenarios.forEach(s => {
|
||||
|
||||
if (s.enable) {
|
||||
let scenario = s.clone();
|
||||
|
||||
let threadGroup = new ThreadGroup(scenario.name || "");
|
||||
|
@ -818,6 +828,7 @@ class JMXGenerator {
|
|||
this.addScenarioCookieManager(threadGroup, scenario);
|
||||
|
||||
scenario.requests.forEach(request => {
|
||||
if (request.enable) {
|
||||
if (!request.isValid()) return;
|
||||
let sampler;
|
||||
|
||||
|
@ -842,9 +853,12 @@ class JMXGenerator {
|
|||
this.addRequestExtractor(sampler, request);
|
||||
|
||||
threadGroup.put(sampler);
|
||||
}
|
||||
})
|
||||
|
||||
testPlan.put(threadGroup);
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
export const LIST_CHANGE = 'LIST_CHANGE';
|
||||
|
||||
export let ApiEvent = new Vue();
|
||||
export let TrackEvent = new Vue();
|
||||
export let PerformanceEvent = new Vue();
|
|
@ -10,25 +10,27 @@
|
|||
<el-submenu v-permission="['test_manager','test_user','test_viewer']"
|
||||
index="3" popper-class="submenu">
|
||||
<template v-slot:title>{{ $t('commons.project') }}</template>
|
||||
<ms-recent-list :options="projectRecent"/>
|
||||
<ms-recent-list ref="projectRecent" :options="projectRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/performance/project/all'"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/performance/project/create'" :title="$t('project.create')"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/performance/project/create'"
|
||||
:title="$t('project.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']"
|
||||
index="4" popper-class="submenu">
|
||||
<template v-slot:title>{{ $t('commons.test') }}</template>
|
||||
<ms-recent-list :options="testRecent"/>
|
||||
<ms-recent-list ref="testRecent" :options="testRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/performance/test/all'"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/performance/test/create'" :title="$t('load_test.create')"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/performance/test/create'"
|
||||
:title="$t('load_test.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']"
|
||||
index="5" popper-class="submenu">
|
||||
<template v-slot:title>{{ $t('commons.report') }}</template>
|
||||
<ms-recent-list :options="reportRecent"/>
|
||||
<ms-recent-list ref="reportRecent" :options="reportRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/performance/report/all'"/>
|
||||
</el-submenu>
|
||||
|
@ -50,6 +52,7 @@
|
|||
import MsRecentList from "../../common/head/RecentList";
|
||||
import MsCreateButton from "../../common/head/CreateButton";
|
||||
import MsShowAll from "../../common/head/ShowAll";
|
||||
import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "PerformanceHeaderMenus",
|
||||
|
@ -92,6 +95,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
PerformanceEvent.$on(LIST_CHANGE, () => {
|
||||
this.$refs.projectRecent.recent();
|
||||
this.$refs.testRecent.recent();
|
||||
this.$refs.reportRecent.recent();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="triggerMode" width="150" :label="'触发方式'" column-key="triggerMode" :filters="triggerFilters">
|
||||
<el-table-column prop="triggerMode" width="150" :label="'触发方式'" column-key="triggerMode"
|
||||
:filters="triggerFilters">
|
||||
<template v-slot:default="scope">
|
||||
<report-trigger-mode-item :trigger-mode="scope.row.triggerMode"/>
|
||||
</template>
|
||||
|
@ -63,8 +64,10 @@
|
|||
width="150"
|
||||
:label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data" @exec="handleEdit(scope.row)" type="primary"/>
|
||||
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')" icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/>
|
||||
<ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data"
|
||||
@exec="handleEdit(scope.row)" type="primary"/>
|
||||
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')"
|
||||
icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -85,13 +88,15 @@
|
|||
import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem";
|
||||
import {REPORT_CONFIGS} from "../../common/components/search/search-components";
|
||||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "PerformanceTestReport",
|
||||
components: {
|
||||
MsTableHeader,
|
||||
ReportTriggerModeItem,
|
||||
MsTableOperatorButton, MsPerformanceReportStatus, MsTablePagination, MsContainer, MsMainContainer},
|
||||
MsTableOperatorButton, MsPerformanceReportStatus, MsTablePagination, MsContainer, MsMainContainer
|
||||
},
|
||||
created: function () {
|
||||
this.initTableData();
|
||||
},
|
||||
|
@ -177,6 +182,8 @@
|
|||
this.result = this.$post(this.deletePath + report.id, {}, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.initTableData();
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
PerformanceEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
},
|
||||
sort(column) {
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
import {_filter, _sort} from "../../../../common/js/utils";
|
||||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import {TEST_CONFIGS} from "../../common/components/search/search-components";
|
||||
import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -192,6 +193,8 @@
|
|||
this.result = this.$post(this.deletePath, data, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.initTableData();
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
PerformanceEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
},
|
||||
sort(column) {
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator :is-tester-permission="true" @editClick="edit(scope.row)" @deleteClick="handleDelete(scope.row)">
|
||||
<ms-table-operator :is-tester-permission="true" @editClick="edit(scope.row)"
|
||||
@deleteClick="handleDelete(scope.row)">
|
||||
<template v-if="baseUrl == 'api'" v-slot:behind>
|
||||
<ms-table-operator-button :is-tester-permission="true" :tip="'环境配置'" icon="el-icon-setting"
|
||||
type="info" @exec="openEnvironmentConfig(scope.row)"/>
|
||||
|
@ -56,10 +57,10 @@
|
|||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input :autosize="{ minRows: 2, maxRows: 4}" type="textarea" v-model="form.description"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="TAPD项目ID" v-if="tapd">
|
||||
<el-form-item :label="$t('project.tapd_id')" v-if="tapd">
|
||||
<el-input v-model="form.tapdId" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="JIRA项目key" v-if="jira">
|
||||
<el-form-item :label="$t('project.jira_key')" v-if="jira">
|
||||
<el-input v-model="form.jiraKey" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -93,6 +94,7 @@
|
|||
import MsTableOperatorButton from "../common/components/MsTableOperatorButton";
|
||||
import ApiEnvironmentConfig from "../api/test/components/ApiEnvironmentConfig";
|
||||
import TemplateComponent from "../track/plan/view/comonents/report/TemplateComponent/TemplateComponent";
|
||||
import {ApiEvent, LIST_CHANGE, PerformanceEvent, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "MsProject",
|
||||
|
@ -102,7 +104,8 @@
|
|||
MsTableOperatorButton,
|
||||
MsDeleteConfirm,
|
||||
MsMainContainer,
|
||||
MsContainer, MsTableOperator, MsCreateBox, MsTablePagination, MsTableHeader, MsDialogFooter},
|
||||
MsContainer, MsTableOperator, MsCreateBox, MsTablePagination, MsTableHeader, MsDialogFooter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
createVisible: false,
|
||||
|
@ -223,6 +226,10 @@
|
|||
this.$get('/project/delete/' + project.id, () => {
|
||||
Message.success(this.$t('commons.delete_success'));
|
||||
this.list();
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
ApiEvent.$emit(LIST_CHANGE);
|
||||
TrackEvent.$emit(LIST_CHANGE);
|
||||
PerformanceEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-card class="header-title" v-loading="result.loading">
|
||||
<div class="header-title" v-loading="result.loading">
|
||||
<div>
|
||||
<div>{{$t('organization.integration.select_defect_platform')}}</div>
|
||||
<el-radio-group v-model="platform" style="margin-top: 10px" @change="change">
|
||||
|
@ -33,7 +33,8 @@
|
|||
</el-button>
|
||||
<el-button v-if="showEdit" size="mini" @click="edit">{{$t('commons.edit')}}</el-button>
|
||||
<el-button type="primary" v-if="showSave" size="mini" @click="save('form')">{{$t('commons.save')}}</el-button>
|
||||
<el-button v-if="showCancel" size="mini" @click="cancelEdit">{{$t('organization.integration.cancel_edit')}}</el-button>
|
||||
<el-button v-if="showCancel" size="mini" @click="cancelEdit">{{$t('organization.integration.cancel_edit')}}
|
||||
</el-button>
|
||||
<el-button type="info" size="mini" @click="cancelIntegration('form')" :disabled="!show">
|
||||
{{$t('organization.integration.cancel_integration')}}
|
||||
</el-button>
|
||||
|
@ -46,11 +47,12 @@
|
|||
</div>
|
||||
<div>
|
||||
2. {{$t('organization.integration.use_tip_two')}}
|
||||
<router-link to="/track/project/all" style="margin-left: 5px">{{$t('organization.integration.link_the_project_now')}}
|
||||
<router-link to="/track/project/all" style="margin-left: 5px">
|
||||
{{$t('organization.integration.link_the_project_now')}}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -69,9 +71,21 @@
|
|||
showSave: false,
|
||||
showCancel: false,
|
||||
rules: {
|
||||
account: {required: true, message: this.$t('organization.integration.input_api_account'), trigger: ['change', 'blur']},
|
||||
password: {required: true, message: this.$t('organization.integration.input_api_password'), trigger: ['change', 'blur']},
|
||||
url: {required: true, message: this.$t('organization.integration.input_jira_url'), trigger: ['change', 'blur']}
|
||||
account: {
|
||||
required: true,
|
||||
message: this.$t('organization.integration.input_api_account'),
|
||||
trigger: ['change', 'blur']
|
||||
},
|
||||
password: {
|
||||
required: true,
|
||||
message: this.$t('organization.integration.input_api_password'),
|
||||
trigger: ['change', 'blur']
|
||||
},
|
||||
url: {
|
||||
required: true,
|
||||
message: this.$t('organization.integration.input_jira_url'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -188,9 +202,14 @@
|
|||
});
|
||||
},
|
||||
testConnection() {
|
||||
if (this.form.account && this.form.password && this.platform) {
|
||||
this.result = this.$get("issues/auth/" + this.platform, () => {
|
||||
this.$success(this.$t('organization.integration.verified'));
|
||||
});
|
||||
} else {
|
||||
this.$warning(this.$t('organization.integration.not_integrated'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-tabs class="system-setting" v-model="activeName">
|
||||
<el-tab-pane :label="$t('organization.defect_manage')" name="defect">
|
||||
<defect-management/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -16,10 +16,22 @@
|
|||
</template>
|
||||
|
||||
<el-table border class="adjust-table" :data="tableData" style="width: 100%">
|
||||
<el-table-column prop="accessKey" label="Access Key"/>
|
||||
<el-table-column prop="accessKey" label="Access Key">
|
||||
<template v-slot:default="scope">
|
||||
<div class="variable-combine">
|
||||
<div class="variable">{{ scope.row.accessKey }}</div>
|
||||
<div>
|
||||
<el-tooltip :content="$t('api_test.copied')" manual v-model="scope.row.visible" placement="top"
|
||||
:visible-arrow="false">
|
||||
<i class="el-icon-copy-document copy" @click="copy(scope.row, 'accessKey', 'visible')"/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="secretKey" label="Secret Key">
|
||||
<template v-slot:default="scope">
|
||||
<el-link type="info" @click="showSecretKey(scope.row)">{{$t('commons.show')}}</el-link>
|
||||
<el-link type="primary" @click="showSecretKey(scope.row)">{{ $t('commons.show') }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" :label="$t('commons.status')">
|
||||
|
@ -46,7 +58,15 @@
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog title="Secret Key" :visible.sync="apiKeysVisible">
|
||||
<div class="variable">
|
||||
{{ currentRow.secretKey }}
|
||||
<el-tooltip :content="$t('api_test.copied')" manual v-model="currentRow.visible2" placement="top"
|
||||
:visible-arrow="false">
|
||||
<i class="el-icon-copy-document copy" @click="copy(currentRow, 'secretKey', 'visible2')"/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -67,6 +87,7 @@
|
|||
apiKeysVisible: false,
|
||||
condition: {},
|
||||
tableData: [],
|
||||
currentRow: {},
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -121,12 +142,50 @@
|
|||
}
|
||||
},
|
||||
showSecretKey(row) {
|
||||
this.$alert(row.secretKey, 'Secret Key');
|
||||
this.apiKeysVisible = true;
|
||||
this.currentRow = row;
|
||||
},
|
||||
copy(row, key, visible) {
|
||||
let input = document.createElement("input");
|
||||
document.body.appendChild(input);
|
||||
input.value = row[key];
|
||||
input.select();
|
||||
if (input.setSelectionRange) {
|
||||
input.setSelectionRange(0, input.value.length);
|
||||
}
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(input);
|
||||
row[visible] = true;
|
||||
setTimeout(() => {
|
||||
row[visible] = false;
|
||||
}, 1000);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.variable-combine {
|
||||
color: #7F7F7F;
|
||||
line-height: 32px;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
margin-right: -20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.variable {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.copy {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
color: #1E90FF;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card class="box-card" v-loading="result.loading">
|
||||
<div v-loading="result.loading">
|
||||
<!--邮件表单-->
|
||||
<el-form :model="formInline" :rules="rules" ref="formInline" class="demo-form-inline"
|
||||
:disabled="show" v-loading="loading" size="small">
|
||||
|
@ -61,7 +60,6 @@
|
|||
</el-button>
|
||||
<el-button @click="cancel" type="info" v-if="showCancel" size="small">{{ $t('commons.cancel') }}</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -71,8 +69,7 @@
|
|||
name: "EmailSetting",
|
||||
data() {
|
||||
return {
|
||||
formInline: {
|
||||
},
|
||||
formInline: {},
|
||||
input: '',
|
||||
visible: true,
|
||||
result: {},
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card class="box-card" v-loading="result.loading">
|
||||
<div v-loading="result.loading">
|
||||
<el-form :model="form" size="small" :rules="rules" :disabled="show" ref="form">
|
||||
<el-form-item :label="$t('ldap.url')" prop="url">
|
||||
<el-input v-model="form.url" :placeholder="$t('ldap.input_url_placeholder')"/>
|
||||
|
@ -33,7 +32,8 @@
|
|||
{{ $t('ldap.test_login') }}
|
||||
</el-button>
|
||||
<el-button v-if="showEdit" size="small" @click="edit">{{ $t('ldap.edit') }}</el-button>
|
||||
<el-button type="success" v-if="showSave" size="small" @click="save('form')">{{$t('commons.save')}}</el-button>
|
||||
<el-button type="success" v-if="showSave" size="small" @click="save('form')">{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
<el-button type="info" v-if="showCancel" size="small" @click="cancel">{{ $t('commons.cancel') }}</el-button>
|
||||
</div>
|
||||
|
||||
|
@ -55,7 +55,6 @@
|
|||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-tabs class="system-setting" v-model="activeName">
|
||||
<el-tab-pane :label="$t('system_parameter_setting.mailbox_service_settings')" name="email">
|
||||
<email-setting/>
|
||||
|
@ -8,12 +8,13 @@
|
|||
<ldap-setting/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EmailSetting from "./EmailSetting";
|
||||
import LdapSetting from "./LdapSetting";
|
||||
|
||||
export default {
|
||||
name: "SystemParameterSetting",
|
||||
components: {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<el-option v-for="(type, index) in typeArr" :key="index" :value="type.id" :label="type.name"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="更新后属性值为" prop="value">
|
||||
<el-form-item :label="$t('test_track.case.updated_attr_value')" prop="value">
|
||||
<el-select v-model="form.value" style="width: 80%" :filterable="filterable">
|
||||
<el-option v-for="(option, index) in options" :key="index" :value="option.id" :label="option.name">
|
||||
<div v-if="option.email">
|
||||
|
@ -47,7 +47,9 @@
|
|||
valueArr: Object,
|
||||
dialogTitle: {
|
||||
type: String,
|
||||
default: "批量操作"
|
||||
default() {
|
||||
return this.$t('test_track.case.batch_operate')
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -56,8 +58,8 @@
|
|||
form: {},
|
||||
size: 0,
|
||||
rules: {
|
||||
type: {required: true, message: "请选择属性", trigger: ['blur','change']},
|
||||
value: {required: true, message: "请选择属性对应的值", trigger: ['blur','change']}
|
||||
type: {required: true, message: this.$t('test_track.case.please_select_attr'), trigger: ['blur','change']},
|
||||
value: {required: true, message: this.$t('test_track.case.please_select_attr_value'), trigger: ['blur','change']}
|
||||
},
|
||||
options: [],
|
||||
filterable: false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-dialog title="选择用例目录"
|
||||
<el-dialog :title="this.$t('test_track.case.select_catalog')"
|
||||
:visible.sync="dialogVisible"
|
||||
:before-close="close"
|
||||
:destroy-on-close="true"
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
</el-card>
|
||||
|
||||
<batch-edit ref="batchEdit" @batchEdit="batchEdit"
|
||||
:typeArr="typeArr" :value-arr="valueArr" dialog-title="批量编辑用例"/>
|
||||
:typeArr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -144,6 +144,7 @@
|
|||
import ShowMoreBtn from "./ShowMoreBtn";
|
||||
import BatchEdit from "./BatchEdit";
|
||||
import {WORKSPACE_ID} from "../../../../../common/js/constants";
|
||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "TestCaseList",
|
||||
|
@ -193,18 +194,18 @@
|
|||
showMore: false,
|
||||
buttons: [
|
||||
{
|
||||
name: '批量编辑用例', handleClick: this.handleBatchEdit
|
||||
name: this.$t('test_track.case.batch_edit_case'), handleClick: this.handleBatchEdit
|
||||
}, {
|
||||
name: '批量移动用例', handleClick: this.handleBatchMove
|
||||
name: this.$t('test_track.case.batch_move_case'), handleClick: this.handleBatchMove
|
||||
}, {
|
||||
name: '批量删除用例', handleClick: this.handleDeleteBatch
|
||||
name: this.$t('test_track.case.batch_delete_case'), handleClick: this.handleDeleteBatch
|
||||
}
|
||||
],
|
||||
typeArr: [
|
||||
{id: 'priority', name: '用例等级'},
|
||||
{id: 'type', name: '类型'},
|
||||
{id: 'method', name: '测试方式'},
|
||||
{id: 'maintainer', name: '维护人'},
|
||||
{id: 'priority', name: this.$t('test_track.case.priority')},
|
||||
{id: 'type', name: this.$t('test_track.case.type')},
|
||||
{id: 'method', name: this.$t('test_track.case.method')},
|
||||
{id: 'maintainer', name: this.$t('test_track.case.maintainer')},
|
||||
],
|
||||
valueArr: {
|
||||
priority: [
|
||||
|
@ -304,6 +305,8 @@
|
|||
this.selectRows.clear();
|
||||
this.$emit("refresh");
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
TrackEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -314,6 +317,8 @@
|
|||
this.$post('/test/case/delete/' + testCaseId, {}, () => {
|
||||
this.initTableData();
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
TrackEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
},
|
||||
refresh() {
|
||||
|
|
|
@ -11,30 +11,33 @@
|
|||
<el-submenu :class="{'deactivation':!isProjectActivation}"
|
||||
v-permission="['test_manager','test_user','test_viewer']" index="3" popper-class="submenu">
|
||||
<template v-slot:title>{{ $t('commons.project') }}</template>
|
||||
<ms-recent-list :options="projectRecent"/>
|
||||
<ms-recent-list ref="projectRecent" :options="projectRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/track/project/all'"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/project/create'" :title="$t('project.create')"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/project/create'"
|
||||
:title="$t('project.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']"
|
||||
index="6" popper-class="submenu">
|
||||
<template v-slot:title>{{ $t('test_track.case.test_case') }}</template>
|
||||
<ms-recent-list :options="caseRecent"/>
|
||||
<ms-recent-list ref="caseRecent" :options="caseRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/track/case/all'"/>
|
||||
<el-menu-item :index="testCaseEditPath" class="blank_item"></el-menu-item>
|
||||
<el-menu-item :index="testCaseProjectPath" class="blank_item"></el-menu-item>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/case/create'" :title="$t('test_track.case.create_case')"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/case/create'"
|
||||
:title="$t('test_track.case.create_case')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']" index="7" popper-class="submenu">
|
||||
<template v-slot:title>{{ $t('test_track.plan.test_plan') }}</template>
|
||||
<ms-recent-list :options="planRecent"/>
|
||||
<ms-recent-list ref="planRecent" :options="planRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/track/plan/all'"/>
|
||||
<el-menu-item :index="testPlanViewPath" class="blank_item"></el-menu-item>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/plan/create'" :title="$t('test_track.plan.create_plan')"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/plan/create'"
|
||||
:title="$t('test_track.plan.create_plan')"/>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</el-col>
|
||||
|
@ -48,6 +51,7 @@
|
|||
import MsShowAll from "../../common/head/ShowAll";
|
||||
import MsRecentList from "../../common/head/RecentList";
|
||||
import MsCreateButton from "../../common/head/CreateButton";
|
||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "TrackHeaderMenus",
|
||||
|
@ -75,7 +79,8 @@
|
|||
index: function (item) {
|
||||
return '/track/case/edit/' + item.id;
|
||||
},
|
||||
router: function (item) {}
|
||||
router: function (item) {
|
||||
}
|
||||
},
|
||||
planRecent: {
|
||||
title: this.$t('test_track.recent_plan'),
|
||||
|
@ -83,7 +88,8 @@
|
|||
index: function (item) {
|
||||
return '/track/plan/view/' + item.id;
|
||||
},
|
||||
router: function (item) {}
|
||||
router: function (item) {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -94,6 +100,11 @@
|
|||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
TrackEvent.$on(LIST_CHANGE, () => {
|
||||
this.$refs.projectRecent.recent();
|
||||
this.$refs.planRecent.recent();
|
||||
this.$refs.caseRecent.recent();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
|
|
|
@ -40,10 +40,12 @@
|
|||
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Prepare'}">
|
||||
{{ $t('test_track.plan.plan_status_prepare') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Underway'}">
|
||||
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
|
||||
:command="{id: scope.row.id, status: 'Underway'}">
|
||||
{{ $t('test_track.plan.plan_status_running') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Completed'}">
|
||||
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
|
||||
:command="{id: scope.row.id, status: 'Completed'}">
|
||||
{{ $t('test_track.plan.plan_status_completed') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
|
@ -87,10 +89,15 @@
|
|||
<el-table-column
|
||||
:label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator :is-tester-permission="true" @editClick="handleEdit(scope.row)" @deleteClick="handleDelete(scope.row)">
|
||||
<ms-table-operator :is-tester-permission="true" @editClick="handleEdit(scope.row)"
|
||||
@deleteClick="handleDelete(scope.row)">
|
||||
<template v-slot:middle>
|
||||
<ms-table-operator-button type="success" v-if="!scope.row.reportId" :tip="$t('test_track.plan_view.create_report')" icon="el-icon-document" @exec="openTestReportTemplate(scope.row)"/>
|
||||
<ms-table-operator-button type="success" v-if="scope.row.reportId" :tip="$t('test_track.plan_view.view_report')" icon="el-icon-document" @exec="openReport(scope.row.id, scope.row.reportId)"/>
|
||||
<ms-table-operator-button :isTesterPermission="true" type="success" v-if="!scope.row.reportId"
|
||||
:tip="$t('test_track.plan_view.create_report')" icon="el-icon-document"
|
||||
@exec="openTestReportTemplate(scope.row)"/>
|
||||
<ms-table-operator-button type="success" v-if="scope.row.reportId"
|
||||
:tip="$t('test_track.plan_view.view_report')" icon="el-icon-document"
|
||||
@exec="openReport(scope.row.id, scope.row.reportId)"/>
|
||||
</template>
|
||||
</ms-table-operator>
|
||||
</template>
|
||||
|
@ -121,6 +128,7 @@
|
|||
import TestCaseReportView from "../view/comonents/report/TestCaseReportView";
|
||||
import MsDeleteConfirm from "../../../common/components/MsDeleteConfirm";
|
||||
import {TEST_PLAN_CONFIGS} from "../../../common/components/search/search-components";
|
||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "TestPlanList",
|
||||
|
@ -130,7 +138,8 @@
|
|||
TestReportTemplateList,
|
||||
PlanStageTableItem,
|
||||
PlanStatusTableItem,
|
||||
MsTableOperator, MsTableOperatorButton, MsDialogFooter, MsTableHeader, MsCreateBox, MsTablePagination},
|
||||
MsTableOperator, MsTableOperatorButton, MsDialogFooter, MsTableHeader, MsCreateBox, MsTablePagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
|
@ -211,6 +220,8 @@
|
|||
this.$post('/test/plan/delete/' + testPlanId, {}, () => {
|
||||
this.initTableData();
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
TrackEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
},
|
||||
intoPlan(row, event, column) {
|
||||
|
|
|
@ -181,7 +181,7 @@
|
|||
:active-text="$t('test_track.plan_view.submit_issues')">
|
||||
</el-switch>
|
||||
<el-tooltip class="item" effect="dark"
|
||||
content="在系统设置-组织-服务集成中集成缺陷管理平台可以自动提交缺陷到指定缺陷管理平台"
|
||||
:content="$t('test_track.issue.platform_tip')"
|
||||
placement="right">
|
||||
<i class="el-icon-info"/>
|
||||
</el-tooltip>
|
||||
|
@ -192,7 +192,7 @@
|
|||
<el-col :span="20" :offset="1" class="issues-edit">
|
||||
<el-input
|
||||
type="text"
|
||||
placeholder="请输入标题"
|
||||
:placeholder="$t('test_track.issue.input_title')"
|
||||
v-model="testCase.issues.title"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
|
@ -207,14 +207,28 @@
|
|||
<el-row>
|
||||
<el-col :span="20" :offset="1" class="issues-edit">
|
||||
<el-table border class="adjust-table" :data="issues" style="width: 100%">
|
||||
<el-table-column prop="id" label="缺陷ID" show-overflow-tooltip/>
|
||||
<el-table-column prop="title" label="缺陷标题"/>
|
||||
<el-table-column prop="description" label="缺陷描述" show-overflow-tooltip/>
|
||||
<el-table-column prop="status" label="缺陷状态"/>
|
||||
<el-table-column prop="platform" label="平台"/>
|
||||
<el-table-column label="操作">
|
||||
<el-table-column prop="id" :label="$t('test_track.issue.id')" show-overflow-tooltip/>
|
||||
<el-table-column prop="title" :label="$t('test_track.issue.title')"/>
|
||||
<el-table-column prop="description" :label="$t('test_track.issue.description')">
|
||||
<template v-slot:default="scope">
|
||||
<el-tooltip content="关闭缺陷"
|
||||
<el-popover
|
||||
placement="left"
|
||||
width="400"
|
||||
trigger="hover"
|
||||
>
|
||||
<ckeditor :editor="editor" disabled
|
||||
v-model="scope.row.description"/>
|
||||
<!-- <span v-html="scope.row.description"/>-->
|
||||
<!-- <span slot="reference">{{scope.row.description}}</span>-->
|
||||
<el-button slot="reference" type="text">预览</el-button>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" :label="$t('test_track.issue.status')"/>
|
||||
<el-table-column prop="platform" :label="$t('test_track.issue.platform')"/>
|
||||
<el-table-column :label="$t('test_track.issue.operate')">
|
||||
<template v-slot:default="scope">
|
||||
<el-tooltip :content="$t('test_track.issue.close')"
|
||||
placement="right">
|
||||
<el-button type="danger" icon="el-icon-circle-close" size="mini"
|
||||
circle v-if="scope.row.platform === 'Local'"
|
||||
|
@ -473,7 +487,7 @@
|
|||
},
|
||||
saveIssues() {
|
||||
if (!this.testCase.issues.title || !this.testCase.issues.content) {
|
||||
this.$warning("标题和描述必填");
|
||||
this.$warning(this.$t('test_track.issue.title_description_required'));
|
||||
return;
|
||||
}
|
||||
let param = {};
|
||||
|
@ -494,7 +508,7 @@
|
|||
closeIssue(row) {
|
||||
this.result = this.$get("/issues/close/" + row.id, () => {
|
||||
this.getIssues(this.testCase.caseId);
|
||||
this.$success("关闭成功");
|
||||
this.$success(this.$t('test_track.issue.close_success'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
|
||||
<el-table-column
|
||||
prop="nodePath"
|
||||
label="缺陷"
|
||||
:label="$t('test_track.issue.issue')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<el-popover
|
||||
|
@ -113,10 +113,24 @@
|
|||
trigger="hover">
|
||||
<el-table border class="adjust-table" :data="scope.row.issuesContent" style="width: 100%">
|
||||
<!-- <el-table-column prop="id" label="缺陷ID" show-overflow-tooltip/>-->
|
||||
<el-table-column prop="title" label="缺陷标题"/>
|
||||
<el-table-column prop="description" label="缺陷描述" show-overflow-tooltip/>
|
||||
<el-table-column prop="title" :label="$t('test_track.issue.title')"/>
|
||||
<el-table-column prop="description" :label="$t('test_track.issue.description')">
|
||||
<template v-slot:default="scope">
|
||||
<el-popover
|
||||
placement="left"
|
||||
width="400"
|
||||
trigger="hover"
|
||||
>
|
||||
<ckeditor :editor="editor" disabled
|
||||
v-model="scope.row.description"/>
|
||||
<!-- <span v-html="scope.row.description"/>-->
|
||||
<!-- <span slot="reference">{{scope.row.description}}</span>-->
|
||||
<el-button slot="reference" type="text">预览</el-button>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column prop="status" label="缺陷状态"/>-->
|
||||
<el-table-column prop="platform" label="平台"/>
|
||||
<el-table-column prop="platform" :label="$t('test_track.issue.platform')"/>
|
||||
</el-table>
|
||||
<el-button slot="reference" type="text">{{scope.row.issuesSize}}</el-button>
|
||||
</el-popover>
|
||||
|
@ -195,7 +209,7 @@
|
|||
<test-case-report-view @refresh="initTableData" ref="testCaseReportView"/>
|
||||
</el-card>
|
||||
<batch-edit ref="batchEdit" @batchEdit="batchEdit"
|
||||
:type-arr="typeArr" :value-arr="valueArr" dialog-title="批量更改测试计划"/>
|
||||
:type-arr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_plan')"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -222,6 +236,7 @@
|
|||
import {TEST_CASE_CONFIGS} from "../../../../common/components/search/search-components";
|
||||
import ShowMoreBtn from "../../../case/components/ShowMoreBtn";
|
||||
import BatchEdit from "../../../case/components/BatchEdit";
|
||||
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
|
||||
|
||||
export default {
|
||||
name: "TestPlanTestCaseList",
|
||||
|
@ -280,15 +295,15 @@
|
|||
showMore: false,
|
||||
buttons: [
|
||||
{
|
||||
name: '批量更改测试计划', handleClick: this.handleBatchEdit
|
||||
name: this.$t('test_track.case.batch_edit_plan'), handleClick: this.handleBatchEdit
|
||||
},
|
||||
{
|
||||
name: '批量取消用例关联', handleClick: this.handleDeleteBatch
|
||||
name: this.$t('test_track.case.batch_unlink'), handleClick: this.handleDeleteBatch
|
||||
}
|
||||
],
|
||||
typeArr: [
|
||||
{id: 'status', name: '执行结果'},
|
||||
{id: 'executor', name: '执行人'},
|
||||
{id: 'status', name: this.$t('test_track.plan_view.execute_result')},
|
||||
{id: 'executor', name: this.$t('test_track.plan_view.executor')},
|
||||
],
|
||||
valueArr: {
|
||||
executor: [],
|
||||
|
@ -298,7 +313,8 @@
|
|||
{name: this.$t('test_track.plan_view.blocking'), id: 'Blocking'},
|
||||
{name: this.$t('test_track.plan_view.skip'), id: 'Skip'}
|
||||
]
|
||||
}
|
||||
},
|
||||
editor: ClassicEditor,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 06fc0a321a9886419be5c607ddaa6b40efb5179b
|
||||
Subproject commit 7e4d80cc2b870a8cac6dbb9fe6711ab6041faf6d
|
|
@ -107,6 +107,7 @@ export default {
|
|||
please_save: 'Please save first',
|
||||
formatErr: 'Format Error',
|
||||
id: 'ID',
|
||||
millisecond: 'ms',
|
||||
please_upload: 'Please upload file',
|
||||
reference_documentation: "Reference documentation",
|
||||
date: {
|
||||
|
@ -213,6 +214,8 @@ export default {
|
|||
owning_workspace: 'Owning Workspace',
|
||||
please_choose_workspace: 'Please select Workspace',
|
||||
special_characters_are_not_supported: 'Incorrect format (special characters are not supported and cannot end with \'-\')',
|
||||
tapd_id: 'TAPD Project ID',
|
||||
jira_key: 'JIRA Project key',
|
||||
},
|
||||
member: {
|
||||
create: 'Create',
|
||||
|
@ -397,7 +400,9 @@ export default {
|
|||
headers: "Headers",
|
||||
kv_description: "Variables are available for all requests",
|
||||
copy: "Copy scenario",
|
||||
delete: "Delete scenario"
|
||||
delete: "Delete scenario",
|
||||
disable: "Disable",
|
||||
enable: "Enable"
|
||||
},
|
||||
request: {
|
||||
copy: "Copy request",
|
||||
|
@ -433,6 +438,9 @@ export default {
|
|||
body: "Body",
|
||||
body_kv: "Key Value",
|
||||
body_text: "Raw",
|
||||
timeout_config: "Timeout Config",
|
||||
connect_timeout: "Connect Timeout",
|
||||
response_timeout: "Response Timeout",
|
||||
assertions: {
|
||||
label: "Assertion",
|
||||
text: "Text",
|
||||
|
@ -587,6 +595,16 @@ export default {
|
|||
relate_test_not_find: 'The associated test does not exist, please check the test case',
|
||||
batch_handle: 'Batch processing (select {0} item)',
|
||||
batch_update: 'Update the attributes of {0} cases',
|
||||
select_catalog: 'Please select use case catalog',
|
||||
updated_attr_value: 'The updated attribute value',
|
||||
batch_operate: 'Batch operation',
|
||||
please_select_attr: 'Please select attributes',
|
||||
please_select_attr_value: 'Please select the value corresponding to the attribute',
|
||||
batch_edit_plan: 'Batch change test plan',
|
||||
batch_edit_case: 'Batch editing test cases',
|
||||
batch_move_case: 'Batch move',
|
||||
batch_delete_case: 'Batch delete',
|
||||
batch_unlink: 'Batch Unlink',
|
||||
import: {
|
||||
import: "Import test case",
|
||||
case_import: "Import test case",
|
||||
|
@ -697,6 +715,20 @@ export default {
|
|||
test_detail: "Test detail",
|
||||
failure_case: "Failure case",
|
||||
export_report: "Export Report"
|
||||
},
|
||||
issue: {
|
||||
issue: "Issue",
|
||||
platform_tip: "Integrated defect management platform in the system setting-organization-service integration can automatically submit defects to the designated defect management platform",
|
||||
input_title: "Please enter title",
|
||||
id: "Issue ID",
|
||||
title: "Issue Title",
|
||||
description: "Issue Description",
|
||||
status: "Issue Status",
|
||||
platform: "Platform",
|
||||
operate: "Operate",
|
||||
close: "Close",
|
||||
title_description_required: "Title and description are required",
|
||||
close_success: "Closed successfully",
|
||||
}
|
||||
},
|
||||
test_resource_pool: {
|
||||
|
|
|
@ -109,6 +109,7 @@ export default {
|
|||
please_save: '请先保存',
|
||||
reference_documentation: "参考文档",
|
||||
id: 'ID',
|
||||
millisecond: '毫秒',
|
||||
date: {
|
||||
select_date: '选择日期',
|
||||
start_date: '开始日期',
|
||||
|
@ -213,6 +214,8 @@ export default {
|
|||
owning_workspace: '所属工作空间',
|
||||
please_choose_workspace: '请选择工作空间',
|
||||
special_characters_are_not_supported: '格式错误(不支持特殊字符,且不能以\'-\'开头结尾)',
|
||||
tapd_id: 'TAPD项目ID',
|
||||
jira_key: 'JIRA项目key',
|
||||
},
|
||||
member: {
|
||||
create: '添加成员',
|
||||
|
@ -397,7 +400,9 @@ export default {
|
|||
headers: "请求头",
|
||||
kv_description: "所有请求可以使用自定义变量",
|
||||
copy: "复制场景",
|
||||
delete: "删除场景"
|
||||
delete: "删除场景",
|
||||
disable: "禁用",
|
||||
enable: "启用"
|
||||
},
|
||||
request: {
|
||||
copy: "复制请求",
|
||||
|
@ -434,6 +439,9 @@ export default {
|
|||
body: "请求内容",
|
||||
body_kv: "键值对",
|
||||
body_text: "文本",
|
||||
timeout_config: "超时设置",
|
||||
connect_timeout: "连接超时",
|
||||
response_timeout: "响应超时",
|
||||
assertions: {
|
||||
label: "断言",
|
||||
text: "文本",
|
||||
|
@ -590,6 +598,16 @@ export default {
|
|||
relate_test_not_find: '关联的测试不存在,请检查用例',
|
||||
batch_handle: '批量处理 (选中{0}项)',
|
||||
batch_update: '更新{0}个用例的属性',
|
||||
select_catalog: '请选择用例目录',
|
||||
updated_attr_value: '更新后属性值为',
|
||||
batch_operate: '批量操作',
|
||||
please_select_attr: '请选择属性',
|
||||
please_select_attr_value: '请选择属性对应的值',
|
||||
batch_edit_plan: '批量更改测试计划',
|
||||
batch_edit_case: '批量编辑用例',
|
||||
batch_move_case: '批量移动用例',
|
||||
batch_delete_case: '批量删除用例',
|
||||
batch_unlink: '批量取消用例关联',
|
||||
import: {
|
||||
import: "导入用例",
|
||||
case_import: "导入测试用例",
|
||||
|
@ -700,6 +718,20 @@ export default {
|
|||
test_detail: "测试详情",
|
||||
failure_case: "失败用例",
|
||||
export_report: "导出报告"
|
||||
},
|
||||
issue: {
|
||||
issue: "缺陷",
|
||||
platform_tip: "在系统设置-组织-服务集成中集成缺陷管理平台可以自动提交缺陷到指定缺陷管理平台",
|
||||
input_title: "请输入标题",
|
||||
id: "缺陷ID",
|
||||
title: "缺陷标题",
|
||||
description: "缺陷描述",
|
||||
status: "缺陷状态",
|
||||
platform: "平台",
|
||||
operate: "操作",
|
||||
close: "关闭缺陷",
|
||||
title_description_required: "标题和描述必填",
|
||||
close_success: "关闭成功",
|
||||
}
|
||||
},
|
||||
test_resource_pool: {
|
||||
|
|
|
@ -105,6 +105,7 @@ export default {
|
|||
formatErr: '格式錯誤',
|
||||
please_save: '請先保存',
|
||||
id: 'ID',
|
||||
millisecond: '毫秒',
|
||||
reference_documentation: "參考文檔",
|
||||
please_upload: '請上傳文件',
|
||||
date: {
|
||||
|
@ -211,6 +212,8 @@ export default {
|
|||
owning_workspace: '所屬工作空間',
|
||||
please_choose_workspace: '請選擇工作空間',
|
||||
special_characters_are_not_supported: '格式錯誤(不支持特殊字符,且不能以\'-\'開頭結尾)',
|
||||
tapd_id: 'TAPD項目ID',
|
||||
jira_key: 'JIRA項目key',
|
||||
},
|
||||
member: {
|
||||
create: '添加成員',
|
||||
|
@ -396,7 +399,9 @@ export default {
|
|||
headers: "請求頭",
|
||||
kv_description: "所有請求可以使用自定義變數",
|
||||
copy: "複製場景",
|
||||
delete: "删除場景"
|
||||
delete: "删除場景",
|
||||
disable: "禁用",
|
||||
enable: "啟用"
|
||||
},
|
||||
request: {
|
||||
copy: "複製請求",
|
||||
|
@ -433,6 +438,9 @@ export default {
|
|||
body: "請求內容",
|
||||
body_kv: "鍵值對",
|
||||
body_text: "文字",
|
||||
timeout_config: "超時設置",
|
||||
connect_timeout: "連接超時",
|
||||
response_timeout: "響應超時",
|
||||
assertions: {
|
||||
label: "斷言",
|
||||
text: "文字",
|
||||
|
@ -587,6 +595,16 @@ export default {
|
|||
relate_test_not_find: '關聯的測試不存在,請檢查用例',
|
||||
batch_handle: '批量處理 (選中{0}項)',
|
||||
batch_update: '更新{0}個用例的屬性',
|
||||
select_catalog: '請選擇用例目錄',
|
||||
updated_attr_value: '更新後屬性值為',
|
||||
batch_operate: '批量操作',
|
||||
please_select_attr: '請選擇屬性',
|
||||
please_select_attr_value: '請選擇屬性對應的值',
|
||||
batch_edit_plan: '批量更改測試計劃',
|
||||
batch_edit_case: '批量編輯用例',
|
||||
batch_move_case: '批量移動用例',
|
||||
batch_delete_case: '批量刪除用例',
|
||||
batch_unlink: '批量取消用例關聯',
|
||||
import: {
|
||||
import: "導入用例",
|
||||
case_import: "導入測試用例",
|
||||
|
@ -697,6 +715,20 @@ export default {
|
|||
test_detail: "測試詳情",
|
||||
failure_case: "失敗用例",
|
||||
export_report: "匯出報告"
|
||||
},
|
||||
issue: {
|
||||
issue: "缺陷",
|
||||
platform_tip: "在系統設置-組織-服務集成中集成缺陷管理平台可以自動提交缺陷到指定缺陷管理平台",
|
||||
input_title: "請輸入標題",
|
||||
id: "缺陷ID",
|
||||
title: "缺陷標題",
|
||||
description: "缺陷描述",
|
||||
status: "缺陷狀態",
|
||||
platform: "平台",
|
||||
operate: "操作",
|
||||
close: "關閉缺陷",
|
||||
title_description_required: "標題和描述必填",
|
||||
close_success: "關閉成功",
|
||||
}
|
||||
},
|
||||
test_resource_pool: {
|
||||
|
|
Loading…
Reference in New Issue