Merge branch 'main' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
b66d5e1ca4
|
@ -230,7 +230,7 @@ public class MsScenario extends MsTestElement {
|
|||
orgJSONArray.forEach(obj -> {
|
||||
JSONObject orgJsonObject = (JSONObject) obj;
|
||||
hashTree.forEach(targetObj -> {
|
||||
if (StringUtils.equals(orgJsonObject.optString(MsHashTreeService.ID), targetObj.getId())) {
|
||||
if (StringUtils.equals(orgJsonObject.optString(MsHashTreeService.RESOURCE_ID), targetObj.getResourceId())) {
|
||||
setRefEnable(targetObj, orgJsonObject);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,10 +3,8 @@ package io.metersphere.api.exec.generator;
|
|||
|
||||
import com.google.gson.*;
|
||||
import io.metersphere.commons.constants.PropertyConstant;
|
||||
import io.metersphere.commons.utils.EnumPropertyUtil;
|
||||
import io.metersphere.commons.utils.JSONUtil;
|
||||
import io.metersphere.jmeter.utils.ScriptEngineUtils;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONArray;
|
||||
|
@ -14,7 +12,6 @@ import org.json.JSONObject;
|
|||
import org.springframework.util.NumberUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
@ -252,12 +249,6 @@ public class JSONSchemaRunTest {
|
|||
if (isMock(object)) {
|
||||
String value = ScriptEngineUtils.buildFunctionCallString(object.get(PropertyConstant.MOCK).getAsJsonObject().get(PropertyConstant.MOCK).getAsString());
|
||||
return value;
|
||||
} else if (object.has(PropertyConstant.ENUM)) {
|
||||
List<Object> list = EnumPropertyUtil.analyzeEnumProperty(object);
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
int index = (int) (Math.random() * list.size());
|
||||
return list.get(index);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return object.get(PropertyConstant.MOCK).getAsJsonObject().get(PropertyConstant.MOCK);
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.metersphere.api.exec.queue;
|
|||
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.jmeter.JMeterThreadUtils;
|
||||
import io.metersphere.cache.JMeterEngineCache;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
|
@ -24,9 +23,6 @@ public class ExecTask implements Runnable {
|
|||
Object res = PoolExecBlockingQueueUtil.take(request.getReportId());
|
||||
if (res == null && !JMeterThreadUtils.isRunning(request.getReportId(), request.getTestId())) {
|
||||
LoggerUtil.info("任务执行超时", request.getReportId());
|
||||
if (JMeterEngineCache.runningEngine.containsKey(request.getReportId())) {
|
||||
JMeterEngineCache.runningEngine.remove(request.getReportId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.metersphere.api.jmeter;
|
|||
|
||||
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||
import io.metersphere.api.jmeter.utils.ReportStatusUtil;
|
||||
import io.metersphere.cache.JMeterEngineCache;
|
||||
import io.metersphere.commons.constants.CommonConstants;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
|
@ -121,9 +120,6 @@ public class MsApiBackendListener extends AbstractBackendListenerClient implemen
|
|||
LoggerUtil.info("进入监听,开始关闭CSV", dto.getReportId());
|
||||
FileServer.getFileServer().closeCsv(dto.getReportId());
|
||||
}
|
||||
if (JMeterEngineCache.runningEngine.containsKey(dto.getReportId())) {
|
||||
JMeterEngineCache.runningEngine.remove(dto.getReportId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
|||
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.cache.JMeterEngineCache;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
|
@ -153,9 +152,6 @@ public class RemakeReportService {
|
|||
dto.setQueueId(request.getQueueId());
|
||||
dto.setTestId(request.getTestId());
|
||||
|
||||
if (JMeterEngineCache.runningEngine.containsKey(dto.getReportId())) {
|
||||
JMeterEngineCache.runningEngine.remove(dto.getReportId());
|
||||
}
|
||||
LoggerUtil.info("进入异常结果处理:" + dto.getRunMode() + " 整体处理完成", dto.getReportId());
|
||||
// 全局并发队列
|
||||
PoolExecBlockingQueueUtil.offer(dto.getReportId());
|
||||
|
|
|
@ -1064,21 +1064,24 @@ public class ApiTestCaseService {
|
|||
}
|
||||
try {
|
||||
List<String> envIds = environments.stream().filter(t -> StringUtils.isNotBlank(t.getValue()) && !StringUtils.equalsIgnoreCase(t.getValue(), "null")).map(ParamsDTO::getValue).collect(Collectors.toList());
|
||||
ApiTestEnvironmentExample example = new ApiTestEnvironmentExample();
|
||||
example.createCriteria().andIdIn(envIds);
|
||||
List<ApiTestEnvironment> environmentList = apiTestEnvironmentMapper.selectByExample(example);
|
||||
if (CollectionUtils.isEmpty(environmentList)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> envMap = environmentList.stream().collect(Collectors.toMap(ApiTestEnvironment::getId, ApiTestEnvironment::getName));
|
||||
if (CollectionUtils.isNotEmpty(envIds)) {
|
||||
ApiTestEnvironmentExample example = new ApiTestEnvironmentExample();
|
||||
example.createCriteria().andIdIn(envIds);
|
||||
List<ApiTestEnvironment> environmentList = apiTestEnvironmentMapper.selectByExample(example);
|
||||
|
||||
Map<String, String> caseEnvMap = environments.stream().filter(t -> StringUtils.isNotBlank(t.getValue()) && !StringUtils.equalsIgnoreCase(t.getValue(), "null")).collect(HashMap::new, (m, v) -> m.put(v.getId(), v.getValue()), HashMap::putAll);
|
||||
caseEnvMap.forEach((k, v) -> {
|
||||
if (envMap.containsKey(v)) {
|
||||
caseEnvMap.put(k, envMap.get(v));
|
||||
if (CollectionUtils.isEmpty(environmentList)) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return caseEnvMap;
|
||||
Map<String, String> envMap = environmentList.stream().collect(Collectors.toMap(ApiTestEnvironment::getId, ApiTestEnvironment::getName));
|
||||
|
||||
Map<String, String> caseEnvMap = environments.stream().filter(t -> StringUtils.isNotBlank(t.getValue()) && !StringUtils.equalsIgnoreCase(t.getValue(), "null")).collect(HashMap::new, (m, v) -> m.put(v.getId(), v.getValue()), HashMap::putAll);
|
||||
caseEnvMap.forEach((k, v) -> {
|
||||
if (envMap.containsKey(v)) {
|
||||
caseEnvMap.put(k, envMap.get(v));
|
||||
}
|
||||
});
|
||||
return caseEnvMap;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("api case environmentId incorrect parsing", e);
|
||||
}
|
||||
|
|
|
@ -4,21 +4,20 @@ import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
|
|||
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.jmeter.JMeterThreadUtils;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||
import io.metersphere.base.mapper.TestResourceMapper;
|
||||
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||
import io.metersphere.base.mapper.ext.BaseTaskMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
|
||||
import io.metersphere.base.mapper.ext.BaseTaskMapper;
|
||||
import io.metersphere.commons.constants.ElementConstants;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.dto.NodeDTO;
|
||||
import io.metersphere.jmeter.LocalRunner;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.task.dto.TaskCenterDTO;
|
||||
import io.metersphere.task.dto.TaskCenterRequest;
|
||||
import io.metersphere.task.dto.TaskRequestDTO;
|
||||
|
@ -213,7 +212,6 @@ public class ExtApiTaskService extends TaskService {
|
|||
}});
|
||||
}
|
||||
} else {
|
||||
new LocalRunner().stop(reportId);
|
||||
JMeterThreadUtils.stop(reportId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -695,6 +695,7 @@ export default {
|
|||
this.reportExportVisible = true;
|
||||
let reset = this.exportReportReset;
|
||||
let name = this.report.name;
|
||||
name = this.encodeSearchKey(name);
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
downloadPDF(document.getElementById('apiTestReport'), name || 'scenario-report');
|
||||
|
@ -702,6 +703,38 @@ export default {
|
|||
}, 5000);
|
||||
});
|
||||
},
|
||||
// 对报告名称中的特殊字符进行编码
|
||||
encodeSearchKey(key) {
|
||||
const encodeArr = [
|
||||
{
|
||||
code: '%',
|
||||
encode: '%25',
|
||||
},
|
||||
{
|
||||
code: '?',
|
||||
encode: '%3F',
|
||||
},
|
||||
{
|
||||
code: '#',
|
||||
encode: '%23',
|
||||
},
|
||||
{
|
||||
code: '&',
|
||||
encode: '%26',
|
||||
},
|
||||
{
|
||||
code: '=',
|
||||
encode: '%3D',
|
||||
},
|
||||
];
|
||||
return key.replace(/[%?#&=]/g, ($, index, str) => {
|
||||
for (const k of encodeArr) {
|
||||
if (k.code === $) {
|
||||
return k.encode;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleSave() {
|
||||
if (!this.report.name) {
|
||||
this.$warning(this.$t('api_test.automation.report_name_info'));
|
||||
|
|
|
@ -328,7 +328,7 @@ export default {
|
|||
debugCode(data) {
|
||||
if (data && this.node && this.node.data) {
|
||||
if (data.error > 0) {
|
||||
this.node.data.code = 'error';
|
||||
this.node.data.code = 'Error';
|
||||
} else {
|
||||
this.node.data.code = this.node.data.code !== 'ERROR' ? 'Success' : 'Error';
|
||||
}
|
||||
|
|
|
@ -133,9 +133,9 @@ export default {
|
|||
getCode() {
|
||||
if (this.node && this.node.data.code && this.node.data.debug) {
|
||||
if (this.node.data.code && this.node.data.code === 'ERROR') {
|
||||
return 'error';
|
||||
return 'Error';
|
||||
} else {
|
||||
return 'success';
|
||||
return 'Success';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
type="primary"
|
||||
size="mini"
|
||||
style="margin: 10px 10px 0px"
|
||||
:disabled="isReadOnly"
|
||||
@click="openOneClickOperation">
|
||||
{{ this.$t('commons.import') }}
|
||||
</el-button>
|
||||
|
@ -24,7 +25,7 @@
|
|||
<json-schema-editor
|
||||
v-if="reloadedApiVariable"
|
||||
class="schema"
|
||||
:disabled="jsonSchemaDisable"
|
||||
:disabled="jsonSchemaDisable || isReadOnly"
|
||||
:value="schema"
|
||||
:show-mock-vars="showMockVars"
|
||||
:scenario-definition="scenarioDefinition"
|
||||
|
@ -82,6 +83,10 @@ export default {
|
|||
return true;
|
||||
},
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (!this.body.jsonSchema && this.body.raw && this.checkIsJson(this.body.raw)) {
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
size="small"
|
||||
maxlength="200"
|
||||
:placeholder="$t('commons.description')"
|
||||
:disabled="isReadOnly"
|
||||
show-word-limit>
|
||||
</el-input>
|
||||
</el-col>
|
||||
|
|
|
@ -47,13 +47,19 @@
|
|||
</div>
|
||||
<div v-if="body.type == 'JSON'">
|
||||
<div style="padding: 10px">
|
||||
<el-switch active-text="JSON-SCHEMA" v-model="body.format" @change="formatChange" active-value="JSON-SCHEMA" />
|
||||
<el-switch
|
||||
active-text="JSON-SCHEMA"
|
||||
v-model="body.format"
|
||||
@change="formatChange"
|
||||
active-value="JSON-SCHEMA"
|
||||
:disabled="isReadOnly" />
|
||||
</div>
|
||||
<ms-json-code-edit
|
||||
v-if="body.format === 'JSON-SCHEMA'"
|
||||
:body="body"
|
||||
:scenario-definition="scenarioDefinition"
|
||||
@editScenarioAdvance="editScenarioAdvance"
|
||||
:is-read-only="isReadOnly"
|
||||
ref="jsonCodeEdit" />
|
||||
<ms-code-edit
|
||||
v-else-if="codeEditActive"
|
||||
|
|
|
@ -21,6 +21,7 @@ public class SessionFilter implements WebFilter {
|
|||
private static final String[] TO_SUB_SERVICE = new String[]{"/license", "/system", "/resource", "/sso/callback/logout", "/sso/callback/cas/logout"};
|
||||
private static final String PERFORMANCE_DOWNLOAD_PREFIX = "/jmeter/";
|
||||
private static final String API_DOWNLOAD_PREFIX = "/api/jmeter/";
|
||||
private static final String TRACK_IMAGE_PREFIX = "/resource/md/get/url";
|
||||
|
||||
@Resource
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
@ -36,15 +37,15 @@ public class SessionFilter implements WebFilter {
|
|||
if (path.startsWith("/css") || path.startsWith("/js")) {
|
||||
for (String prefix : PREFIX) {
|
||||
if (path.contains(prefix)) {
|
||||
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, req.getURI());
|
||||
String newPath = prefix + path;
|
||||
ServerHttpRequest request = req.mutate().path(newPath).build();
|
||||
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, request.getURI());
|
||||
return chain.filter(exchange.mutate().request(request).build());
|
||||
return addPrefix(prefix, exchange, chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path.startsWith(TRACK_IMAGE_PREFIX)) {
|
||||
return addPrefix("/track", exchange, chain);
|
||||
}
|
||||
|
||||
// 有些url直接转到 sub-service
|
||||
for (String prefix : TO_SUB_SERVICE) {
|
||||
if (path.startsWith(prefix)) {
|
||||
|
@ -53,31 +54,29 @@ public class SessionFilter implements WebFilter {
|
|||
break;
|
||||
}
|
||||
String service = svc.get();
|
||||
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, req.getURI());
|
||||
String newPath = "/" + service + "/" + path;
|
||||
ServerHttpRequest request = req.mutate().path(newPath).build();
|
||||
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, request.getURI());
|
||||
return chain.filter(exchange.mutate().request(request).build());
|
||||
return addPrefix("/" + service + "/", exchange, chain);
|
||||
}
|
||||
}
|
||||
|
||||
// 从当前站点下载资源
|
||||
if (path.startsWith(PERFORMANCE_DOWNLOAD_PREFIX)) {
|
||||
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, req.getURI());
|
||||
String newPath = "/performance" + path;
|
||||
ServerHttpRequest request = req.mutate().path(newPath).build();
|
||||
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, request.getURI());
|
||||
return chain.filter(exchange.mutate().request(request).build());
|
||||
return addPrefix("/performance", exchange, chain);
|
||||
}
|
||||
|
||||
if (path.startsWith(API_DOWNLOAD_PREFIX)) {
|
||||
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, req.getURI());
|
||||
String newPath = "/api" + path;
|
||||
ServerHttpRequest request = req.mutate().path(newPath).build();
|
||||
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, request.getURI());
|
||||
return chain.filter(exchange.mutate().request(request).build());
|
||||
return addPrefix("/api", exchange, chain);
|
||||
}
|
||||
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
private Mono<Void> addPrefix(String prefix, final ServerWebExchange exchange, final WebFilterChain chain) {
|
||||
ServerHttpRequest req = exchange.getRequest();
|
||||
String path = req.getURI().getRawPath();
|
||||
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, req.getURI());
|
||||
String newPath = prefix + path;
|
||||
ServerHttpRequest request = req.mutate().path(newPath).build();
|
||||
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, request.getURI());
|
||||
return chain.filter(exchange.mutate().request(request).build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,10 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
|
@ -243,6 +246,8 @@ public class SSOService {
|
|||
RestTemplate restTemplate = getRestTemplateIgnoreSSL();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
|
||||
String credentials = EncryptUtils.base64Encoding(config.get("clientId") + ":" + config.get("secret"));
|
||||
headers.add(HttpHeaders.AUTHORIZATION, "Basic " + credentials);
|
||||
HttpEntity<String> param = new HttpEntity<>(headers);
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(url, param, String.class);
|
||||
String content = response.getBody();
|
||||
|
@ -263,7 +268,7 @@ public class SSOService {
|
|||
|
||||
private Optional<SessionUser> doOauth2Login(AuthSource authSource, String accessToken, WebSession session, Locale locale) throws Exception {
|
||||
Map<String, String> oauth2Config = null;
|
||||
Map<String, String> resultObj = null;
|
||||
Map<String, Object> resultObj = null;
|
||||
try {
|
||||
oauth2Config = JSON.parseObject(authSource.getConfiguration(), new TypeReference<HashMap<String, String>>() {});
|
||||
String userInfoUrl = oauth2Config.get("userInfoUrl");
|
||||
|
@ -272,7 +277,7 @@ public class SSOService {
|
|||
RestTemplate restTemplate = getRestTemplateIgnoreSSL();
|
||||
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(headers);
|
||||
ResponseEntity<String> response = restTemplate.exchange(userInfoUrl, HttpMethod.GET, httpEntity, String.class);
|
||||
resultObj = JSON.parseObject(response.getBody(), new TypeReference<HashMap<String, String>>() {});
|
||||
resultObj = JSON.parseObject(response.getBody(), new TypeReference<HashMap<String, Object>>() {});
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("fail to get user info", e);
|
||||
MSException.throwException("fail to get user info!");
|
||||
|
@ -281,9 +286,9 @@ public class SSOService {
|
|||
String attrMapping = oauth2Config.get("mapping");
|
||||
Map<String, String> mapping = this.getOauth2AttrMapping(attrMapping);
|
||||
|
||||
String userid = resultObj.get(mapping.get("userid"));
|
||||
String username = resultObj.get(mapping.get("username"));
|
||||
String email = resultObj.get(mapping.get("email"));
|
||||
String userid = (String) resultObj.get(mapping.get("userid"));
|
||||
String username = (String) resultObj.get(mapping.get("username"));
|
||||
String email = (String) resultObj.get(mapping.get("email"));
|
||||
|
||||
if (StringUtils.isBlank(userid)) {
|
||||
MSException.throwException("userid is empty!");
|
||||
|
|
|
@ -281,6 +281,8 @@ export default {
|
|||
.ms-right-fixed {
|
||||
flex: 0;
|
||||
margin-left: 0px;
|
||||
height: calc(100vh);
|
||||
background-color: #F5F6F7;
|
||||
}
|
||||
|
||||
.ms-header-w {
|
||||
|
|
|
@ -329,10 +329,12 @@ export default {
|
|||
if (source.type === 'OAuth2') {
|
||||
url = config.authUrl
|
||||
+ "?client_id=" + config.clientId
|
||||
+ "&scope=" + config.scope
|
||||
+ "&response_type=code"
|
||||
+ "&redirect_uri=" + redirectUrl
|
||||
+ "&state=" + authId;
|
||||
if (config.scope) {
|
||||
url += "&scope=" + config.scope;
|
||||
}
|
||||
}
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
sync_add_api_load: 'Synchronously add associated api and load tests',
|
||||
sync_add_api_load: 'Synchronously add associated test case',
|
||||
next: 'Next',
|
||||
total_size: 'Total {0}',
|
||||
related_requirements: 'Related requirements',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
sync_add_api_load: '同步添加关联的接口和性能测试',
|
||||
sync_add_api_load: '同步添加关联测试的用例',
|
||||
next: '下一条',
|
||||
total_size: '共 {0} 条',
|
||||
related_requirements: '关联需求',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
sync_add_api_load: '同步添加關聯的接口和性能測試',
|
||||
sync_add_api_load: '同步添加關聯測試的用例',
|
||||
next: '下一條',
|
||||
total_size: '共 {0} 條',
|
||||
related_requirements: '關聯需求',
|
||||
|
|
|
@ -2027,7 +2027,8 @@ const message = {
|
|||
api: "接口用例",
|
||||
scene: "场景用例",
|
||||
load: "性能用例",
|
||||
functional: "功能用例"
|
||||
functional: "功能用例",
|
||||
ui: "UI用例",
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package io.metersphere.cache;
|
||||
|
||||
import org.apache.jmeter.engine.StandardJMeterEngine;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class JMeterEngineCache {
|
||||
/**
|
||||
* 执行中的线程池
|
||||
*/
|
||||
public static ConcurrentHashMap<String, StandardJMeterEngine> runningEngine = new ConcurrentHashMap<>();
|
||||
|
||||
}
|
|
@ -1,15 +1,10 @@
|
|||
package io.metersphere.jmeter;
|
||||
|
||||
import io.metersphere.cache.JMeterEngineCache;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.engine.JMeterEngineException;
|
||||
import org.apache.jmeter.engine.StandardJMeterEngine;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LocalRunner {
|
||||
private HashTree jmxTree;
|
||||
|
||||
|
@ -26,31 +21,8 @@ public class LocalRunner {
|
|||
try {
|
||||
LoggerUtil.info("LocalRunner 开始执行报告",report);
|
||||
engine.runTest();
|
||||
JMeterEngineCache.runningEngine.put(report, engine);
|
||||
} catch (JMeterEngineException e) {
|
||||
engine.stopTest(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(List<String> reports) {
|
||||
if (CollectionUtils.isNotEmpty(reports)) {
|
||||
for (String report : reports) {
|
||||
StandardJMeterEngine engine = JMeterEngineCache.runningEngine.get(report);
|
||||
if (engine != null) {
|
||||
engine.stopTest();
|
||||
JMeterEngineCache.runningEngine.remove(report);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(String report) {
|
||||
if (StringUtils.isNotEmpty(report)) {
|
||||
StandardJMeterEngine engine = JMeterEngineCache.runningEngine.get(report);
|
||||
if (engine != null) {
|
||||
engine.stopTest();
|
||||
JMeterEngineCache.runningEngine.remove(report);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package io.metersphere.service.utils;
|
||||
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Service
|
||||
public class MsClassLoader {
|
||||
|
||||
public final static ConcurrentHashMap<String, MsURLClassLoader> LOADER_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
public MsURLClassLoader loadJar(String path) {
|
||||
try {
|
||||
String jarName = path.substring(path.indexOf("_") + 1);
|
||||
if (StringUtils.isNotEmpty(jarName) && jarName.endsWith(".jar")) {
|
||||
jarName = jarName.substring(0, jarName.length() - 4);
|
||||
}
|
||||
MsURLClassLoader urlClassLoader = LOADER_CACHE.get(jarName);
|
||||
if (urlClassLoader != null) {
|
||||
return urlClassLoader;
|
||||
}
|
||||
urlClassLoader = new MsURLClassLoader();
|
||||
File jarFile = new File(path);
|
||||
URL jarUrl = jarFile.toURI().toURL();
|
||||
urlClassLoader.addURLFile(jarUrl);
|
||||
LOADER_CACHE.put(jarName, urlClassLoader);
|
||||
return urlClassLoader;
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error("加载JAR包失败:" + ex.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Class loadClass(String jarName, String name) throws ClassNotFoundException {
|
||||
if (StringUtils.isNotEmpty(jarName) && jarName.endsWith(".jar")) {
|
||||
jarName = jarName.substring(0, jarName.length() - 4);
|
||||
}
|
||||
MsURLClassLoader urlClassLoader = LOADER_CACHE.get(jarName);
|
||||
if (urlClassLoader == null) {
|
||||
return null;
|
||||
}
|
||||
return urlClassLoader.loadClass(name);
|
||||
}
|
||||
|
||||
public void unloadJarFile(String path) throws MalformedURLException {
|
||||
String jarName = path.substring(path.indexOf("_") + 1);
|
||||
if (StringUtils.isNotEmpty(jarName) && jarName.endsWith(".jar")) {
|
||||
jarName = jarName.substring(0, jarName.length() - 4);
|
||||
}
|
||||
MsURLClassLoader urlClassLoader = LOADER_CACHE.get(jarName);
|
||||
if (urlClassLoader == null) {
|
||||
return;
|
||||
}
|
||||
urlClassLoader.unloadJarFile(path);
|
||||
urlClassLoader = null;
|
||||
LOADER_CACHE.remove(jarName);
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
package io.metersphere.service.utils;
|
||||
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class MsURLClassLoader extends URLClassLoader {
|
||||
private JarURLConnection cachedJarFile = null;
|
||||
|
||||
public MsURLClassLoader() {
|
||||
super(new URL[]{}, findParentClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定的文件url添加到类加载器的classpath中去,并缓存jar connection,方便以后卸载jar
|
||||
* 一个可想类加载器的classpath中添加的文件url
|
||||
*
|
||||
* @param
|
||||
*/
|
||||
public void addURLFile(URL file) {
|
||||
try {
|
||||
// 打开并缓存文件url连接
|
||||
URLConnection uc = file.openConnection();
|
||||
if (uc instanceof JarURLConnection) {
|
||||
uc.setUseCaches(true);
|
||||
((JarURLConnection) uc).getManifest();
|
||||
cachedJarFile = (JarURLConnection) uc;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to cache plugin JAR file: " + file.toExternalForm());
|
||||
}
|
||||
addURL(file);
|
||||
}
|
||||
|
||||
|
||||
public void unloadJarFile(String url) {
|
||||
JarURLConnection jarURLConnection = cachedJarFile;
|
||||
if (jarURLConnection == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
System.err.println("Unloading plugin JAR file " + jarURLConnection.getJarFile().getName());
|
||||
jarURLConnection.getJarFile().close();
|
||||
jarURLConnection = null;
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to unload JAR file\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 定位基于当前上下文的父类加载器
|
||||
*
|
||||
* @return 返回可用的父类加载器.
|
||||
*/
|
||||
private static ClassLoader findParentClassLoader() {
|
||||
ClassLoader parent = ClassLoader.getSystemClassLoader();
|
||||
if (parent == null) {
|
||||
parent = MsURLClassLoader.class.getClassLoader();
|
||||
}
|
||||
if (parent == null) {
|
||||
parent = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
}
|
|
@ -233,7 +233,7 @@
|
|||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item label="Scope" :rules="requiredRules" prop="configuration.scope">
|
||||
<el-form-item label="Scope" prop="configuration.scope">
|
||||
<el-input v-model="form.configuration.scope"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
|
@ -79,11 +79,11 @@ public interface ExtTestCaseMapper {
|
|||
|
||||
List<TrackCountResult> countStatus(@Param("projectId") String projectId);
|
||||
|
||||
List<TrackCountResult> countRelevance(@Param("projectId") String projectId);
|
||||
List<TrackCountResult> countRelevance(@Param("projectId") String projectId, @Param("queryUI") boolean queryUI);
|
||||
|
||||
long countRelevanceCreatedThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
|
||||
|
||||
int countCoverage(@Param("projectId") String projectId);
|
||||
int countCoverage(@Param("projectId") String projectId, @Param("queryUi") boolean queryUi);
|
||||
|
||||
List<TrackCountResult> countFuncMaintainer(@Param("projectId") String projectId);
|
||||
|
||||
|
|
|
@ -836,7 +836,14 @@
|
|||
FROM test_case_test
|
||||
WHERE test_type = 'automation'
|
||||
and test_id IN (select id FROM api_scenario WHERE `STATUS` != 'Trash')
|
||||
)
|
||||
<if test="queryUI">
|
||||
UNION
|
||||
SELECT test_case_id, test_id, test_type
|
||||
FROM test_case_test
|
||||
WHERE test_type = 'uiAutomation'
|
||||
and test_id IN (select id FROM ui_scenario WHERE `STATUS` != 'Trash')
|
||||
</if>
|
||||
)
|
||||
test_case_test
|
||||
ON test_case.id = test_case_test.test_case_id
|
||||
WHERE
|
||||
|
@ -869,6 +876,11 @@
|
|||
UNION
|
||||
SELECT test_case_id FROM test_case_test WHERE test_type = 'automation' and test_id IN (select id FROM
|
||||
api_scenario WHERE `STATUS` != 'Trash')
|
||||
<if test="queryUi">
|
||||
UNION
|
||||
SELECT test_case_id FROM test_case_test WHERE test_type = 'uiAutomation' and test_id IN (select id FROM
|
||||
ui_scenario WHERE `STATUS` != 'Trash')
|
||||
</if>
|
||||
)
|
||||
</select>
|
||||
<select id="countFuncMaintainer" resultType="io.metersphere.dto.TrackCountResult">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package io.metersphere.constants;
|
||||
|
||||
public enum TestCaseTestType {
|
||||
testcase, automation, performance
|
||||
testcase, automation, performance, uiAutomation
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.controller;
|
|||
|
||||
|
||||
import io.metersphere.base.domain.TestCase;
|
||||
import io.metersphere.commons.constants.MicroServiceName;
|
||||
import io.metersphere.dto.BugStatistics;
|
||||
import io.metersphere.dto.TrackCountResult;
|
||||
import io.metersphere.dto.TrackStatisticsDTO;
|
||||
|
@ -9,6 +10,7 @@ import io.metersphere.i18n.Translator;
|
|||
import io.metersphere.plan.dto.ChartsData;
|
||||
import io.metersphere.service.TestCaseService;
|
||||
import io.metersphere.service.TrackService;
|
||||
import io.metersphere.utils.DiscoveryUtil;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -21,7 +23,6 @@ import java.util.List;
|
|||
@RestController
|
||||
@RequestMapping("/track")
|
||||
public class TrackController {
|
||||
|
||||
@Resource
|
||||
private TrackService trackService;
|
||||
@Resource
|
||||
|
@ -61,7 +62,8 @@ public class TrackController {
|
|||
public TrackStatisticsDTO getRelevanceCount(@PathVariable String projectId) {
|
||||
TrackStatisticsDTO statistics = new TrackStatisticsDTO();
|
||||
|
||||
List<TrackCountResult> relevanceResults = trackService.countRelevance(projectId);
|
||||
boolean queryUi = DiscoveryUtil.hasService(MicroServiceName.UI_TEST);
|
||||
List<TrackCountResult> relevanceResults = trackService.countRelevance(projectId, queryUi);
|
||||
statistics.countRelevance(relevanceResults);
|
||||
|
||||
long size = trackService.countRelevanceCreatedThisWeek(projectId);
|
||||
|
@ -69,7 +71,7 @@ public class TrackController {
|
|||
|
||||
List<TestCase> list = testCaseService.getTestCaseByProjectId(projectId);
|
||||
long total = list.size();
|
||||
int coverage = trackService.countCoverage(projectId);
|
||||
int coverage = trackService.countCoverage(projectId, queryUi);
|
||||
statistics.setCoverageCount(coverage);
|
||||
statistics.setUncoverageCount(total - coverage);
|
||||
|
||||
|
@ -82,6 +84,9 @@ public class TrackController {
|
|||
statistics.setApiCaseCountStr(Translator.get("api_case") + "<br/><br/>" + statistics.getApiCaseCount());
|
||||
statistics.setPerformanceCaseCountStr(Translator.get("performance_case") + "<br/><br/>" + statistics.getPerformanceCaseCount());
|
||||
statistics.setScenarioCaseStr(Translator.get("scenario_case") + "<br/><br/>" + statistics.getScenarioCaseCount());
|
||||
if (queryUi) {
|
||||
statistics.setUiScenarioCaseStr(Translator.get("ui_scenario_case") + "<br/><br/>" + statistics.getUiScenarioCaseCount());
|
||||
}
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@ import javax.servlet.http.HttpServletRequest;
|
|||
"/test/plan/uiScenario/case",
|
||||
"/ui/scenario/module",
|
||||
"/share/test/plan/uiScenario/case",
|
||||
"/ui/automation"
|
||||
"/ui/automation",
|
||||
"/test/case/relevance/uiScenario"
|
||||
})
|
||||
public class TrackUiTestController {
|
||||
@Resource
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
public enum TestCaseTestStatus {
|
||||
performance, api, testcase, automation
|
||||
performance, api, testcase, automation, uiAutomation
|
||||
}
|
||||
|
|
|
@ -69,10 +69,16 @@ public class TrackStatisticsDTO {
|
|||
*/
|
||||
private long performanceCaseCount = 0;
|
||||
|
||||
/**
|
||||
* UI场景用例数量统计
|
||||
*/
|
||||
private long uiScenarioCaseCount = 0;
|
||||
|
||||
|
||||
private String apiCaseCountStr = StringUtils.EMPTY;
|
||||
private String scenarioCaseStr = StringUtils.EMPTY;
|
||||
private String performanceCaseCountStr = StringUtils.EMPTY;
|
||||
private String uiScenarioCaseStr = StringUtils.EMPTY;
|
||||
|
||||
/**
|
||||
* 本周新增数量
|
||||
|
@ -187,6 +193,15 @@ public class TrackStatisticsDTO {
|
|||
chartData.put(Translator.get("scenario_case"), count);
|
||||
}
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(TrackCount.UI_AUTOMATION, countResult.getGroupField())) {
|
||||
Integer count = chartData.get(Translator.get("ui_scenario_case"));
|
||||
if (count == null) {
|
||||
chartData.put(Translator.get("ui_scenario_case"), (int) countResult.getCountNumber());
|
||||
} else {
|
||||
count += (int) countResult.getCountNumber();
|
||||
chartData.put(Translator.get("ui_scenario_case"), count);
|
||||
}
|
||||
}
|
||||
this.allRelevanceCaseCount += countResult.getCountNumber();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,5 +28,8 @@ public class PlanCaseRelevanceRequest {
|
|||
*/
|
||||
private List<String> testCaseIds = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 是否同步关联功能用例下关联的接口场景性能ui用例
|
||||
*/
|
||||
private Boolean checked;
|
||||
}
|
||||
|
|
|
@ -628,22 +628,30 @@ public class TestPlanService {
|
|||
List<String> apiCaseIds = new ArrayList<>();
|
||||
List<String> scenarioIds = new ArrayList<>();
|
||||
List<String> performanceIds = new ArrayList<>();
|
||||
buildCaseIdList(list, apiCaseIds, scenarioIds, performanceIds);
|
||||
startRelevance(request, apiCaseIds, scenarioIds, performanceIds);
|
||||
List<String> uiScenarioIds = new ArrayList<>();
|
||||
buildCaseIdList(list, apiCaseIds, scenarioIds, performanceIds, uiScenarioIds);
|
||||
startRelevance(request, apiCaseIds, scenarioIds, performanceIds, uiScenarioIds);
|
||||
}
|
||||
|
||||
private void startRelevance(PlanCaseRelevanceRequest request, List<String> apiCaseIds, List<String> scenarioIds, List<String> performanceIds) {
|
||||
private void startRelevance(PlanCaseRelevanceRequest request, List<String> apiCaseIds, List<String> scenarioIds, List<String> performanceIds, List<String> uiScenarioIds) {
|
||||
Set<String> serviceIdSet = DiscoveryUtil.getServiceIdSet();
|
||||
if (serviceIdSet.contains(MicroServiceName.API_TEST)) {
|
||||
planTestPlanApiCaseService.relevanceByTestIds(apiCaseIds, request.getPlanId());
|
||||
planTestPlanScenarioCaseService.relevanceByTestIds(scenarioIds, request.getPlanId());
|
||||
if (CollectionUtils.isNotEmpty(apiCaseIds)) {
|
||||
planTestPlanApiCaseService.relevanceByTestIds(apiCaseIds, request.getPlanId());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(scenarioIds)) {
|
||||
planTestPlanScenarioCaseService.relevanceByTestIds(scenarioIds, request.getPlanId());
|
||||
}
|
||||
}
|
||||
if (serviceIdSet.contains(MicroServiceName.PERFORMANCE_TEST)) {
|
||||
if (serviceIdSet.contains(MicroServiceName.PERFORMANCE_TEST) && CollectionUtils.isNotEmpty(performanceIds)) {
|
||||
planTestPlanLoadCaseService.relevanceByTestIds(performanceIds, request.getPlanId());
|
||||
}
|
||||
if (serviceIdSet.contains(MicroServiceName.UI_TEST) && CollectionUtils.isNotEmpty(uiScenarioIds)) {
|
||||
planTestPlanUiScenarioCaseService.relevanceByTestIds(uiScenarioIds, request.getPlanId());
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildCaseIdList(List<TestCaseTest> list, List<String> apiCaseIds, List<String> scenarioIds, List<String> performanceIds) {
|
||||
private static void buildCaseIdList(List<TestCaseTest> list, List<String> apiCaseIds, List<String> scenarioIds, List<String> performanceIds, List<String> uiScenarioIds) {
|
||||
for (TestCaseTest l : list) {
|
||||
if (StringUtils.equals(l.getTestType(), TestCaseTestStatus.performance.name())) {
|
||||
performanceIds.add(l.getTestId());
|
||||
|
@ -654,6 +662,9 @@ public class TestPlanService {
|
|||
if (StringUtils.equals(l.getTestType(), TestCaseTestStatus.automation.name())) {
|
||||
scenarioIds.add(l.getTestId());
|
||||
}
|
||||
if (StringUtils.equals(l.getTestType(), TestCaseTestStatus.uiAutomation.name())) {
|
||||
uiScenarioIds.add(l.getTestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.util.*;
|
|||
@Service
|
||||
public class PlanTestPlanUiScenarioCaseService extends UiTestService {
|
||||
|
||||
private static final String BASE_UEL = "/test/plan/uiScenario/case";
|
||||
private static final String BASE_URL = "/test/plan/uiScenario/case";
|
||||
|
||||
@Resource
|
||||
private PlanTestPlanScenarioCaseService planTestPlanScenarioCaseService;
|
||||
|
@ -41,11 +41,11 @@ public class PlanTestPlanUiScenarioCaseService extends UiTestService {
|
|||
TestPlanService testPlanService;
|
||||
|
||||
public List<String> getExecResultByPlanId(String planId) {
|
||||
return (List<String>) microService.getForData(serviceName, BASE_UEL + "/plan/exec/result/" + planId);
|
||||
return (List<String>) microService.getForData(serviceName, BASE_URL + "/plan/exec/result/" + planId);
|
||||
}
|
||||
|
||||
public UiPlanReportDTO getUiReport(ApiPlanReportRequest request) {
|
||||
return microService.postForData(serviceName, BASE_UEL + "/plan/report", request, UiPlanReportDTO.class);
|
||||
return microService.postForData(serviceName, BASE_URL + "/plan/report", request, UiPlanReportDTO.class);
|
||||
}
|
||||
|
||||
public void calculatePlanReport(List<String> reportIds, TestPlanSimpleReportDTO report) {
|
||||
|
@ -93,20 +93,20 @@ public class PlanTestPlanUiScenarioCaseService extends UiTestService {
|
|||
|
||||
|
||||
private TestPlanScenarioStepCountSimpleDTO getStepCount(List<PlanReportCaseDTO> planReportCaseDTOS) {
|
||||
return microService.postForData(serviceName, BASE_UEL + "/step/count", planReportCaseDTOS, TestPlanScenarioStepCountSimpleDTO.class);
|
||||
return microService.postForData(serviceName, BASE_URL + "/step/count", planReportCaseDTOS, TestPlanScenarioStepCountSimpleDTO.class);
|
||||
}
|
||||
|
||||
public List<PlanReportCaseDTO> selectStatusForPlanReport(String planId) {
|
||||
return microService.getForDataArray(serviceName, BASE_UEL + "/get/report/status/" + planId, PlanReportCaseDTO.class);
|
||||
return microService.getForDataArray(serviceName, BASE_URL + "/get/report/status/" + planId, PlanReportCaseDTO.class);
|
||||
}
|
||||
|
||||
public void copyPlan(String sourcePlanId, String targetPlanId) {
|
||||
microService.getForData(serviceName, BASE_UEL + "/plan/copy/" + sourcePlanId + "/" + targetPlanId);
|
||||
microService.getForData(serviceName, BASE_URL + "/plan/copy/" + sourcePlanId + "/" + targetPlanId);
|
||||
}
|
||||
|
||||
public boolean haveUiCase(String planId) {
|
||||
try {
|
||||
return (boolean) microService.getForData(serviceName, BASE_UEL + "/have/ui/case/" + planId);
|
||||
return (boolean) microService.getForData(serviceName, BASE_URL + "/have/ui/case/" + planId);
|
||||
} catch (MSException e) {
|
||||
LogUtil.error(e);
|
||||
return false;
|
||||
|
@ -114,34 +114,38 @@ public class PlanTestPlanUiScenarioCaseService extends UiTestService {
|
|||
}
|
||||
|
||||
public List<TestPlanUiScenario> list(String planId) {
|
||||
return microService.getForDataArray(serviceName, BASE_UEL + "/list/" + planId, TestPlanUiScenario.class);
|
||||
return microService.getForDataArray(serviceName, BASE_URL + "/list/" + planId, TestPlanUiScenario.class);
|
||||
}
|
||||
|
||||
public Boolean isCaseExecuting(String planId) {
|
||||
return (Boolean) microService.getForData(serviceName, BASE_UEL + "/is/executing/" + planId);
|
||||
return (Boolean) microService.getForData(serviceName, BASE_URL + "/is/executing/" + planId);
|
||||
}
|
||||
|
||||
public List<TestPlanUiScenarioDTO> getFailureListByIds(Set<String> ids) {
|
||||
return microService.postForDataArray(serviceName, BASE_UEL + "/failure/list", ids, TestPlanUiScenarioDTO.class);
|
||||
return microService.postForDataArray(serviceName, BASE_URL + "/failure/list", ids, TestPlanUiScenarioDTO.class);
|
||||
}
|
||||
|
||||
public List<ModuleNodeDTO> getNodeByPlanId(List<String> projectIds, String planId) {
|
||||
return microService.postForDataArray(serviceName, BASE_UEL + "/list/module/" + planId, projectIds, ModuleNodeDTO.class);
|
||||
return microService.postForDataArray(serviceName, BASE_URL + "/list/module/" + planId, projectIds, ModuleNodeDTO.class);
|
||||
}
|
||||
|
||||
public List<TestPlanUiScenarioDTO> buildResponse(List<TestPlanUiScenarioDTO> uiCases) {
|
||||
if (CollectionUtils.isEmpty(uiCases)) {
|
||||
return null;
|
||||
}
|
||||
return microService.postForDataArray(serviceName, BASE_UEL + "/build/response", uiCases, TestPlanUiScenarioDTO.class);
|
||||
return microService.postForDataArray(serviceName, BASE_URL + "/build/response", uiCases, TestPlanUiScenarioDTO.class);
|
||||
}
|
||||
|
||||
public Object relevanceList(ApiScenarioRequest request, int pageNum, int pageSize) {
|
||||
request.setAllowedRepeatCase(testPlanService.isAllowedRepeatCase(request.getPlanId()));
|
||||
return microService.postForData(serviceName, BASE_UEL + String.format("/relevance/list/%s/%s", pageNum, pageSize), request);
|
||||
return microService.postForData(serviceName, BASE_URL + String.format("/relevance/list/%s/%s", pageNum, pageSize), request);
|
||||
}
|
||||
|
||||
public void orderCase(ResetOrderRequest request) {
|
||||
microService.postForData(serviceName, BASE_UEL + "/edit/order", request);
|
||||
microService.postForData(serviceName, BASE_URL + "/edit/order", request);
|
||||
}
|
||||
|
||||
public void relevanceByTestIds(List<String> uiScenarioIds, String planId) {
|
||||
microService.postForData(serviceName, BASE_URL + "/relevance/" + planId, uiScenarioIds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,4 +9,5 @@ public class TrackCount {
|
|||
public static final String TESTCASE = "testcase";
|
||||
public static final String PERFORMANCE = "performance";
|
||||
public static final String AUTOMATION = "automation";
|
||||
public static final String UI_AUTOMATION = "uiAutomation";
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import io.metersphere.plan.service.TestPlanTestCaseService;
|
|||
import io.metersphere.request.OrderRequest;
|
||||
import io.metersphere.request.ProjectVersionRequest;
|
||||
import io.metersphere.request.ResetOrderRequest;
|
||||
import io.metersphere.service.remote.ui.RelevanceUiCaseService;
|
||||
import io.metersphere.xpack.track.dto.AttachmentRequest;
|
||||
import io.metersphere.request.member.QueryMemberRequest;
|
||||
import io.metersphere.request.testcase.*;
|
||||
|
@ -145,6 +146,8 @@ public class TestCaseService {
|
|||
private RelevanceApiCaseService relevanceApiCaseService;
|
||||
@Resource
|
||||
private RelevanceLoadCaseService relevanceLoadCaseService;
|
||||
@Resource
|
||||
private RelevanceUiCaseService relevanceUiCaseService;
|
||||
// @Resource
|
||||
// @Lazy
|
||||
// private ApiTestCaseService apiTestCaseService;
|
||||
|
@ -2593,6 +2596,7 @@ public class TestCaseService {
|
|||
List<ApiTestCase> apiCases = new ArrayList<>();
|
||||
List<ApiScenario> apiScenarios = new ArrayList<>();
|
||||
List<LoadTest> apiLoadTests = new ArrayList<>();
|
||||
List<UiScenario> uiScenarios = new ArrayList<>();
|
||||
|
||||
if (serviceIdSet.contains(MicroServiceName.API_TEST)) {
|
||||
apiCases = relevanceApiCaseService.getApiCaseByIds(
|
||||
|
@ -2612,6 +2616,13 @@ public class TestCaseService {
|
|||
versionIds.addAll(apiLoadTests.stream().map(l -> l.getVersionId()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
if (serviceIdSet.contains(MicroServiceName.UI_TEST)) {
|
||||
uiScenarios = relevanceUiCaseService.getUiCaseByIds(
|
||||
getTestIds(testCaseTests, TestCaseTestType.uiAutomation.name()));
|
||||
projectIds.addAll(uiScenarios.stream().map(s -> s.getProjectId()).collect(Collectors.toList()));
|
||||
versionIds.addAll(uiScenarios.stream().map(l -> l.getVersionId()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
|
||||
projectIds = projectIds.stream().distinct().collect(Collectors.toList());
|
||||
versionIds = versionIds.stream().distinct().collect(Collectors.toList());
|
||||
|
@ -2647,6 +2658,10 @@ public class TestCaseService {
|
|||
getTestCaseTestDaoList(TestCaseTestType.performance.name(), item.getNum(), item.getName(), item.getId(), projectNameMap.get(item.getProjectId()), versionNameMap.get(item.getVersionId()),
|
||||
testCaseTestList, testCaseTestsMap);
|
||||
});
|
||||
uiScenarios.forEach(item -> {
|
||||
getTestCaseTestDaoList(TestCaseTestType.uiAutomation.name(), item.getNum(), item.getName(), item.getId(), projectNameMap.get(item.getProjectId()), versionNameMap.get(item.getVersionId()),
|
||||
testCaseTestList, testCaseTestsMap);
|
||||
});
|
||||
return testCaseTestList;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,8 +94,8 @@ public class TrackService {
|
|||
return extTestCaseMapper.countStatus(projectId);
|
||||
}
|
||||
|
||||
public List<TrackCountResult> countRelevance(String projectId) {
|
||||
return extTestCaseMapper.countRelevance(projectId);
|
||||
public List<TrackCountResult> countRelevance(String projectId, boolean queryUI) {
|
||||
return extTestCaseMapper.countRelevance(projectId, queryUI);
|
||||
}
|
||||
|
||||
public long countRelevanceCreatedThisWeek(String projectId) {
|
||||
|
@ -111,8 +111,8 @@ public class TrackService {
|
|||
}
|
||||
}
|
||||
|
||||
public int countCoverage(String projectId) {
|
||||
return extTestCaseMapper.countCoverage(projectId);
|
||||
public int countCoverage(String projectId, boolean queryUi) {
|
||||
return extTestCaseMapper.countCoverage(projectId, queryUi);
|
||||
}
|
||||
|
||||
public List<ChartsData> getCaseMaintenanceBar(String projectId) {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.service.remote.ui;
|
||||
|
||||
import io.metersphere.base.domain.UiScenario;
|
||||
import io.metersphere.service.remote.project.TrackUiTestService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class RelevanceUiCaseService extends TrackUiTestService {
|
||||
|
||||
private static final String BASE_URL = "/test/case";
|
||||
|
||||
public List<UiScenario> getUiCaseByIds(List<String> ids) {
|
||||
return microService.postForDataArray(serviceName, BASE_URL + "/getUiCaseByIds", ids, UiScenario.class);
|
||||
}
|
||||
}
|
|
@ -188,6 +188,7 @@ message_task_already_exists=Task recipient already exists
|
|||
api_case=Api
|
||||
performance_case=Performance
|
||||
scenario_case=Scenario
|
||||
ui_scenario_case=UI Scenario
|
||||
create_user=Create user
|
||||
test_case_status=Case status
|
||||
id_not_rightful=ID is not rightful
|
||||
|
|
|
@ -161,6 +161,7 @@ message_task_already_exists=任务接收人已经存在
|
|||
api_case=接口用例
|
||||
performance_case=性能用例
|
||||
scenario_case=场景用例
|
||||
ui_scenario_case=UI用例
|
||||
test_case_status_error=失败
|
||||
test_case_status_success=成功
|
||||
test_case_status_trash=废弃
|
||||
|
|
|
@ -161,6 +161,7 @@ message_task_already_exists=任務接收人已經存在
|
|||
api_case=接口用例
|
||||
performance_case=性能用例
|
||||
scenario_case=場景用例
|
||||
ui_scenario_case=UI用例
|
||||
test_case_status_error=失敗
|
||||
test_case_status_success=成功
|
||||
test_case_status_trash=廢棄
|
||||
|
|
|
@ -233,6 +233,10 @@ export function getTestCaseRelevanceScenarioList(pageNum, pageSize, param) {
|
|||
return post(BASE_URL + "relevance/scenario/list/" + pageNum + "/" + pageSize, param);
|
||||
}
|
||||
|
||||
export function getTestCaseRelevanceUiScenarioList(pageNum, pageSize, param) {
|
||||
return post(BASE_URL + "relevance/uiScenario/list/" + pageNum + "/" + pageSize, param);
|
||||
}
|
||||
|
||||
export function getTestCaseRelevanceLoadList(pageNum, pageSize, param) {
|
||||
return post(BASE_URL + "relevance/load/list/" + pageNum + "/" + pageSize, param);
|
||||
}
|
||||
|
@ -245,6 +249,10 @@ export function saveCaseRelevanceScenario(caseId, param) {
|
|||
return post(BASE_URL + "relate/test/automation/" + caseId, param);
|
||||
}
|
||||
|
||||
export function saveUiCaseRelevanceScenario(caseId, param) {
|
||||
return post(BASE_URL + "relate/test/uiAutomation/" + caseId, param);
|
||||
}
|
||||
|
||||
export function saveCaseRelevanceLoad(caseId, param) {
|
||||
return post(BASE_URL + "relate/test/performance/" + caseId, param);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="right-search">
|
||||
<version-select v-xpack :project-id="projectId" @changeVersion="changeVersion" margin-right="20"/>
|
||||
|
||||
<el-input :placeholder="$t('commons.search_by_name_or_id')" @blur="initTable"
|
||||
@keyup.enter.native="initTable" class="search-input" size="small" v-model="condition.name"/>
|
||||
|
||||
<ms-table-adv-search-bar :condition.sync="condition" class="adv-search-bar"
|
||||
v-if="condition.components !== undefined && condition.components.length > 0"
|
||||
@search="initTable"/>
|
||||
</div>
|
||||
|
||||
<ms-table v-loading="result.loading" :data="tableData" :select-node-ids="selectNodeIds" :condition="condition"
|
||||
:page-size="pageSize"
|
||||
:total="total"
|
||||
:showSelectAll="false"
|
||||
:screenHeight="screenHeight"
|
||||
@selectCountChange="selectCountChange"
|
||||
@refresh="initTable"
|
||||
ref="table">
|
||||
|
||||
<ms-table-column
|
||||
prop="num"
|
||||
label="ID"
|
||||
width="100px"
|
||||
sortable=true>
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column
|
||||
prop="name"
|
||||
:label="$t('api_test.automation.scenario_name')"/>
|
||||
|
||||
<ms-table-column
|
||||
prop="level"
|
||||
sortable
|
||||
min-width="130px"
|
||||
:label="$t('api_test.automation.case_level')">
|
||||
<template v-slot:default="scope">
|
||||
<priority-table-item :value="scope.row.level"/>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column prop="status"
|
||||
:label="$t('test_track.plan.plan_status')"
|
||||
sortable
|
||||
min-width="120px">
|
||||
<template v-slot:default="scope">
|
||||
<plan-status-table-item :value="scope.row.status"/>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column prop="tags" width="120px" :label="$t('commons.tag')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain"
|
||||
:content="itemName" style="margin-left: 0px; margin-right: 2px"/>
|
||||
<span></span>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
</ms-table>
|
||||
<ms-table-pagination :change="initTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MsTable from "metersphere-frontend/src/components/table/MsTable";
|
||||
import MsTableColumn from "metersphere-frontend/src/components/table/MsTableColumn";
|
||||
import PriorityTableItem from "@/business/common/tableItems/planview/PriorityTableItem";
|
||||
import MsTablePagination from "metersphere-frontend/src/components/pagination/TablePagination";
|
||||
import PlanStatusTableItem from "@/business/common/tableItems/plan/PlanStatusTableItem";
|
||||
import MsTableAdvSearchBar from "metersphere-frontend/src/components/search/MsTableAdvSearchBar";
|
||||
import MsTag from "metersphere-frontend/src/components/MsTag";
|
||||
import {TEST_CASE_RELEVANCE_API_CASE_CONFIGS} from "metersphere-frontend/src/components/search/search-components";
|
||||
import {getVersionFilters} from "@/business/utils/sdk-utils";
|
||||
import MxVersionSelect from "metersphere-frontend/src/components/version/MxVersionSelect";
|
||||
import {getTestCaseRelevanceScenarioList, getTestCaseRelevanceUiScenarioList} from "@/api/testCase";
|
||||
|
||||
export default {
|
||||
name: "TestCaseRelateUiScenarioList",
|
||||
components: {
|
||||
PlanStatusTableItem,
|
||||
MsTablePagination,
|
||||
PriorityTableItem,
|
||||
MsTable,
|
||||
MsTableColumn,
|
||||
MsTableAdvSearchBar,
|
||||
MsTag,
|
||||
'VersionSelect': MxVersionSelect,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
condition: {
|
||||
components: TEST_CASE_RELEVANCE_API_CASE_CONFIGS
|
||||
},
|
||||
result: {},
|
||||
priorityFilters: [
|
||||
{text: 'P0', value: 'P0'},
|
||||
{text: 'P1', value: 'P1'},
|
||||
{text: 'P2', value: 'P2'},
|
||||
{text: 'P3', value: 'P3'}
|
||||
],
|
||||
screenHeight: 'calc(100vh - 400px)',//屏幕高度
|
||||
tableData: [],
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
versionFilters: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
selectNodeIds: Array,
|
||||
projectId: String,
|
||||
versionEnable: Boolean,
|
||||
notInIds: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
testCaseId: String
|
||||
},
|
||||
created: function () {
|
||||
this.getVersionOptions();
|
||||
},
|
||||
watch: {
|
||||
selectNodeIds() {
|
||||
this.initTable();
|
||||
},
|
||||
projectId() {
|
||||
this.condition.versionId = null;
|
||||
this.initTable();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectRows() {
|
||||
if (this.$refs.table) {
|
||||
return this.$refs.table.getSelectRows();
|
||||
} else {
|
||||
return new Set();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectCountChange(data) {
|
||||
this.$emit("selectCountChange", data);
|
||||
},
|
||||
initTable(projectId) {
|
||||
this.condition.status = "";
|
||||
this.condition.moduleIds = this.selectNodeIds;
|
||||
if (projectId != null && typeof projectId === 'string') {
|
||||
this.condition.projectId = projectId;
|
||||
} else if (this.projectId != null) {
|
||||
this.condition.projectId = this.projectId;
|
||||
}
|
||||
this.condition.notInIds = this.notInIds;
|
||||
this.condition.testCaseId = this.testCaseId;
|
||||
getTestCaseRelevanceUiScenarioList(this.currentPage, this.pageSize, this.condition)
|
||||
.then(response => {
|
||||
this.total = response.data.itemCount;
|
||||
this.tableData = response.data.listObject;
|
||||
this.tableData.forEach(item => {
|
||||
if (item.tags && item.tags.length > 0) {
|
||||
item.tags = JSON.parse(item.tags);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
clear() {
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.clear();
|
||||
}
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + this.currentPage + "/" + this.pageSize;
|
||||
},
|
||||
getSelectIds() {
|
||||
return this.$refs.table.selectIds;
|
||||
},
|
||||
clearSelection() {
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.clearSelectRows();
|
||||
}
|
||||
},
|
||||
getVersionOptions() {
|
||||
getVersionFilters(this.projectId)
|
||||
.then(r => this.versionFilters = r.data);
|
||||
},
|
||||
changeVersion(currentVersion) {
|
||||
this.condition.versionId = currentVersion || null;
|
||||
this.initTable();
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.right-search {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 300px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.adv-search-bar {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
|
@ -8,6 +8,7 @@
|
|||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="api">{{ $t('api_test.home_page.failed_case_list.table_value.case_type.api') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="scenario">{{ $t('api_test.home_page.failed_case_list.table_value.case_type.scene') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="ui" v-xpack>{{ $t('api_test.home_page.failed_case_list.table_value.case_type.ui') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="performance">{{$t('api_test.home_page.failed_case_list.table_value.case_type.load')}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
@ -61,6 +62,13 @@
|
|||
@refresh="initTable"
|
||||
ref="apiScenarioRelevance"/>
|
||||
|
||||
<test-case-ui-scenario-relate
|
||||
:case-id="caseId"
|
||||
:versionEnable="versionEnable"
|
||||
:not-in-ids="notInIds"
|
||||
@refresh="initTable"
|
||||
ref="uiScenarioRelevance"/>
|
||||
|
||||
<test-case-load-relate
|
||||
:case-id="caseId"
|
||||
:not-in-ids="notInIds"
|
||||
|
@ -77,11 +85,15 @@ import MsTableColumn from "metersphere-frontend/src/components/table/MsTableColu
|
|||
import TestCaseApiRelate from "@/business/case/components/TestCaseApiRelate";
|
||||
import {deleteRelateTest, getRelateTest} from "@/api/testCase";
|
||||
import TestCaseScenarioRelate from "@/business/case/components/TestCaseScenarioRelate";
|
||||
import TestCaseUiScenarioRelate from "@/business/case/components/TestCaseUiScenarioRelate";
|
||||
import TestCaseLoadRelate from "@/business/case/components/TestCaseLoadRelate";
|
||||
import i18n from "@/i18n";
|
||||
import TestCaseUiScenarioRelevance from "@/business/plan/view/comonents/ui/TestCaseUiScenarioRelevance";
|
||||
|
||||
export default {
|
||||
name: "TestCaseTestRelate",
|
||||
components: {TestCaseLoadRelate, TestCaseScenarioRelate, TestCaseApiRelate, MsTableColumn, MsTable},
|
||||
components: {
|
||||
TestCaseUiScenarioRelevance,
|
||||
TestCaseLoadRelate, TestCaseScenarioRelate, TestCaseApiRelate, MsTableColumn, MsTable, TestCaseUiScenarioRelate},
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
|
@ -89,7 +101,8 @@ export default {
|
|||
typeMap: {
|
||||
testcase: this.$t('api_test.home_page.failed_case_list.table_value.case_type.api'),
|
||||
automation: this.$t('api_test.home_page.failed_case_list.table_value.case_type.scene'),
|
||||
performance: this.$t('api_test.home_page.failed_case_list.table_value.case_type.load')
|
||||
performance: this.$t('api_test.home_page.failed_case_list.table_value.case_type.load'),
|
||||
uiAutomation: this.$t('api_test.home_page.failed_case_list.table_value.case_type.ui')
|
||||
},
|
||||
operators: [
|
||||
{
|
||||
|
@ -122,6 +135,8 @@ export default {
|
|||
this.$refs.apiScenarioRelevance.open();
|
||||
} else if (key === 'performance') {
|
||||
this.$refs.loadRelevance.open();
|
||||
} else if (key === 'ui') {
|
||||
this.$refs.uiScenarioRelevance.open();
|
||||
}
|
||||
},
|
||||
remove(row) {
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<template>
|
||||
|
||||
<test-case-relevance-base
|
||||
@setProject="setProject"
|
||||
@save="saveCaseRelevance"
|
||||
ref="baseRelevance">
|
||||
|
||||
<template v-slot:aside>
|
||||
<ui-scenario-module
|
||||
:show-case-num="false"
|
||||
:relevance-project-id="projectId"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@refreshTable="refresh"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
@enableTrash="false"
|
||||
:is-read-only="true"
|
||||
ref="nodeTree"/>
|
||||
</template>
|
||||
|
||||
<test-case-relate-ui-scenario-list
|
||||
:select-node-ids="selectNodeIds"
|
||||
:project-id="projectId"
|
||||
:not-in-ids="notInIds"
|
||||
:versionEnable="versionEnable"
|
||||
:test-case-id="caseId"
|
||||
@selectCountChange="setSelectCounts"
|
||||
ref="apiCaseList"/>
|
||||
|
||||
</test-case-relevance-base>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import TestCaseRelateApiList from "@/business/case/components/TestCaseRelateApiList";
|
||||
import TestCaseRelevanceBase from "@/business/plan/view/comonents/base/TestCaseRelevanceBase";
|
||||
import UiScenarioModule from "@/business/plan/view/comonents/ui/UiScenarioModule";
|
||||
import TestCaseRelateUiScenarioList from "@/business/case/components/TestCaseRelateUiScenarioList";
|
||||
import {saveUiCaseRelevanceScenario} from "@/api/testCase";
|
||||
|
||||
export default {
|
||||
name: "TestCaseUiScenarioRelate",
|
||||
components: {
|
||||
TestCaseRelateUiScenarioList,
|
||||
UiScenarioModule,
|
||||
TestCaseRelevanceBase,
|
||||
TestCaseRelateApiList,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectNodeIds: [],
|
||||
moduleOptions: {},
|
||||
condition: {},
|
||||
projectId: ""
|
||||
};
|
||||
},
|
||||
props: {
|
||||
caseId: {
|
||||
type: String
|
||||
},
|
||||
versionEnable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
notInIds: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.init();
|
||||
this.$refs.baseRelevance.open();
|
||||
if (this.$refs.apiCaseList) {
|
||||
this.$refs.apiCaseList.clear();
|
||||
}
|
||||
},
|
||||
init() {
|
||||
if (this.$refs.apiCaseList) {
|
||||
this.$refs.apiCaseList.initTable();
|
||||
}
|
||||
if (this.$refs.nodeTree) {
|
||||
this.$refs.nodeTree.list();
|
||||
}
|
||||
},
|
||||
setProject(projectId) {
|
||||
this.projectId = projectId;
|
||||
},
|
||||
|
||||
refresh(data) {
|
||||
this.$refs.apiCaseList.initTable(data);
|
||||
},
|
||||
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.selectNodeIds = nodeIds;
|
||||
},
|
||||
setModuleOptions(data) {
|
||||
this.moduleOptions = data;
|
||||
},
|
||||
saveCaseRelevance() {
|
||||
let ids = this.$refs.apiCaseList.getSelectIds();
|
||||
saveUiCaseRelevanceScenario(this.caseId, ids)
|
||||
.then(() => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit('refresh');
|
||||
this.$refs.baseRelevance.close();
|
||||
});
|
||||
},
|
||||
setSelectCounts(data) {
|
||||
this.$refs.baseRelevance.selectCounts = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -1,4 +1,4 @@
|
|||
<template>
|
||||
<template>
|
||||
<div class="dashboard-card">
|
||||
<el-card shadow="never" class="box-card" style="height: 100%">
|
||||
<div slot="header" class="clearfix">
|
||||
|
|
|
@ -59,7 +59,9 @@
|
|||
shareId,
|
||||
isPlanReport: true,
|
||||
isTemplate,
|
||||
response
|
||||
response,
|
||||
showCancelButton: false,
|
||||
showReportNameButton: false
|
||||
}"/>
|
||||
<UiShareReportDetail
|
||||
v-else
|
||||
|
|
|
@ -165,7 +165,8 @@
|
|||
<!-- 执行结果 -->
|
||||
<el-drawer :visible.sync="runVisible" :destroy-on-close="true" direction="ltr" :withHeader="true" :modal="false"
|
||||
size="90%">
|
||||
<micro-app :to="`/ui/report/view/${reportId}?showCancelButton=false`" service="ui"/>
|
||||
<micro-app :to="`/ui/report/view/${reportId}`" route-name="ApiReportView"
|
||||
:route-params="{showCancelButton: false, reportId}" service="ui"/>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
|
@ -35,6 +35,7 @@ const TRACK_HEADER = {
|
|||
{id: 'testPlanTestCaseCount', key: 'g', label: 'test_track.plan.test_plan_test_case_count'},
|
||||
{id: 'testPlanApiCaseCount', key: 'h', label: 'test_track.plan.test_plan_api_case_count'},
|
||||
{id: 'testPlanApiScenarioCount', key: 'i', label: 'test_track.plan.test_plan_api_scenario_count'},
|
||||
{id: 'testPlanUiScenarioCount', key: 'l', label: 'test_track.plan.test_plan_ui_scenario_count', xpack: true},
|
||||
{id: 'testPlanLoadCaseCount', key: 'j', label: 'test_track.plan.test_plan_load_case_count'},
|
||||
{id: 'principalName', key: 'k', label: 'test_track.plan.plan_principal'},
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue