Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
fed9519fce
|
@ -18,10 +18,6 @@ MeterSphere 是一站式的开源企业级持续测试平台,涵盖测试跟
|
||||||
|
|
||||||
> 如需进一步了解 MeterSphere 开源项目,推荐阅读 [MeterSphere 的初心和使命](https://mp.weixin.qq.com/s/DpCt3BNgBTlV3sJ5qtPmZw)
|
> 如需进一步了解 MeterSphere 开源项目,推荐阅读 [MeterSphere 的初心和使命](https://mp.weixin.qq.com/s/DpCt3BNgBTlV3sJ5qtPmZw)
|
||||||
|
|
||||||
## UI 展示
|
|
||||||
|
|
||||||
![UI](https://metersphere.io/images/screenshot/ss01.png)
|
|
||||||
|
|
||||||
## 在线体验
|
## 在线体验
|
||||||
- 环境地址:https://demo.metersphere.com/
|
- 环境地址:https://demo.metersphere.com/
|
||||||
- 用户名:demo
|
- 用户名:demo
|
||||||
|
|
|
@ -37,4 +37,8 @@ public class SqlRequest implements Request {
|
||||||
private JSR223PreProcessor jsr223PreProcessor;
|
private JSR223PreProcessor jsr223PreProcessor;
|
||||||
@JSONField(ordinal = 12)
|
@JSONField(ordinal = 12)
|
||||||
private JSR223PostProcessor jsr223PostProcessor;
|
private JSR223PostProcessor jsr223PostProcessor;
|
||||||
|
@JSONField(ordinal = 13)
|
||||||
|
private String resultVariable;
|
||||||
|
@JSONField(ordinal = 14)
|
||||||
|
private String variableNames;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.api.parse;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.parser.Feature;
|
||||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||||
import io.metersphere.api.dto.parse.ApiImport;
|
import io.metersphere.api.dto.parse.ApiImport;
|
||||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||||
|
@ -23,7 +24,7 @@ public class MsParser extends ApiImportAbstractParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String parsePluginFormat(String testStr) {
|
private String parsePluginFormat(String testStr) {
|
||||||
JSONObject testObject = JSONObject.parseObject(testStr);
|
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
|
||||||
if (testObject.get("scenarios") != null) {
|
if (testObject.get("scenarios") != null) {
|
||||||
return testStr;
|
return testStr;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
public class KafkaProperties {
|
public class KafkaProperties {
|
||||||
public static final String KAFKA_PREFIX = "kafka";
|
public static final String KAFKA_PREFIX = "kafka";
|
||||||
|
|
||||||
private String acks;
|
private String acks = "all";
|
||||||
private String topic;
|
private String topic;
|
||||||
private String fields;
|
private String fields;
|
||||||
private String timestamp;
|
private String timestamp;
|
||||||
|
|
|
@ -81,8 +81,8 @@ public class TestPlanController {
|
||||||
|
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
public void editTestPlan(@RequestBody TestPlan testPlan) {
|
public void editTestPlan(@RequestBody TestPlanDTO testPlanDTO) {
|
||||||
testPlanService.editTestPlan(testPlan);
|
testPlanService.editTestPlan(testPlanDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/edit/status/{planId}")
|
@PostMapping("/edit/status/{planId}")
|
||||||
|
|
|
@ -4,8 +4,11 @@ import io.metersphere.base.domain.TestPlan;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class TestPlanDTO extends TestPlan {
|
public class TestPlanDTO extends TestPlan {
|
||||||
private String projectName;
|
private String projectName;
|
||||||
|
private List<String> projectIds;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -110,12 +111,51 @@ public class TestPlanService {
|
||||||
return Optional.ofNullable(testPlanMapper.selectByPrimaryKey(testPlanId)).orElse(new TestPlan());
|
return Optional.ofNullable(testPlanMapper.selectByPrimaryKey(testPlanId)).orElse(new TestPlan());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int editTestPlan(TestPlan testPlan) {
|
public int editTestPlan(TestPlanDTO testPlan) {
|
||||||
|
editTestPlanProject(testPlan);
|
||||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||||
checkTestPlanExist(testPlan);
|
checkTestPlanExist(testPlan);
|
||||||
return testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
return testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void editTestPlanProject(TestPlanDTO testPlan) {
|
||||||
|
List<String> projectIds = testPlan.getProjectIds();
|
||||||
|
if (!CollectionUtils.isEmpty(projectIds)) {
|
||||||
|
TestPlanProjectExample testPlanProjectExample1 = new TestPlanProjectExample();
|
||||||
|
testPlanProjectExample1.createCriteria().andTestPlanIdEqualTo(testPlan.getId());
|
||||||
|
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample1);
|
||||||
|
// 已经关联的项目idList
|
||||||
|
List<String> dbProjectIds = testPlanProjects.stream().map(TestPlanProject::getProjectId).collect(Collectors.toList());
|
||||||
|
// 修改后传过来的项目idList,如果还未关联,进行关联
|
||||||
|
projectIds.forEach(projectId -> {
|
||||||
|
if (!dbProjectIds.contains(projectId)) {
|
||||||
|
TestPlanProject testPlanProject = new TestPlanProject();
|
||||||
|
testPlanProject.setTestPlanId(testPlan.getId());
|
||||||
|
testPlanProject.setProjectId(projectId);
|
||||||
|
testPlanProjectMapper.insert(testPlanProject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
|
||||||
|
testPlanProjectExample.createCriteria().andTestPlanIdEqualTo(testPlan.getId()).andProjectIdNotIn(projectIds);
|
||||||
|
testPlanProjectMapper.deleteByExample(testPlanProjectExample);
|
||||||
|
|
||||||
|
// 关联的项目下的用例idList
|
||||||
|
TestCaseExample example = new TestCaseExample();
|
||||||
|
example.createCriteria().andProjectIdIn(projectIds);
|
||||||
|
List<TestCase> caseList = testCaseMapper.selectByExample(example);
|
||||||
|
List<String> caseIds = caseList.stream().map(TestCase::getId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 取消关联所属项目下的用例和计划的关系
|
||||||
|
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
||||||
|
TestPlanTestCaseExample.Criteria criteria = testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(testPlan.getId());
|
||||||
|
if (!CollectionUtils.isEmpty(caseIds)) {
|
||||||
|
criteria.andCaseIdNotIn(caseIds);
|
||||||
|
}
|
||||||
|
testPlanTestCaseMapper.deleteByExample(testPlanTestCaseExample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkTestPlanExist(TestPlan testPlan) {
|
private void checkTestPlanExist(TestPlan testPlan) {
|
||||||
if (testPlan.getName() != null) {
|
if (testPlan.getName() != null) {
|
||||||
TestPlanExample example = new TestPlanExample();
|
TestPlanExample example = new TestPlanExample();
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class XmindToTestCaseParser {
|
||||||
// 递归处理案例数据
|
// 递归处理案例数据
|
||||||
private void makeXmind(StringBuffer processBuffer, Attached parent, int level, String nodePath, List<Attached> attacheds) {
|
private void makeXmind(StringBuffer processBuffer, Attached parent, int level, String nodePath, List<Attached> attacheds) {
|
||||||
for (Attached item : attacheds) {
|
for (Attached item : attacheds) {
|
||||||
if (isBlack(item.getTitle(), "(?:tc|tc)")) { // 用例
|
if (isBlack(item.getTitle(), "(?:tc:|tc:|tc)")) { // 用例
|
||||||
item.setParent(parent);
|
item.setParent(parent);
|
||||||
this.newTestCase(item.getTitle(), parent.getPath(), item.getChildren() != null ? item.getChildren().getAttached() : null);
|
this.newTestCase(item.getTitle(), parent.getPath(), item.getChildren() != null ? item.getChildren().getAttached() : null);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 321c869938357e8c2253e5bd86c963828664ae23
|
Subproject commit d5b4969642fd8d10cc2f949d7377e0a0e5217a3a
|
|
@ -40,7 +40,6 @@ spring.flyway.validate-on-migrate=false
|
||||||
spring.messages.basename=i18n/messages
|
spring.messages.basename=i18n/messages
|
||||||
|
|
||||||
# kafka
|
# kafka
|
||||||
kafka.acks=1
|
|
||||||
kafka.fields=
|
kafka.fields=
|
||||||
kafka.timestamp=yyyy-MM-dd'T'HH:mm:ss.SSSZZ
|
kafka.timestamp=yyyy-MM-dd'T'HH:mm:ss.SSSZZ
|
||||||
kafka.sample-filter=
|
kafka.sample-filter=
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<el-col v-if="auth">
|
<el-col v-if="auth">
|
||||||
|
<el-row id="header-top1" type="flex" justify="space-between" align="middle">
|
||||||
|
<el-col>
|
||||||
|
<div class="license-head" v-if="valid === true && validData.status == 'expired'">License has expired since
|
||||||
|
{{(validData!= undefined && validData.license!= undefined) ? validData.license.expired:''}},please
|
||||||
|
update license.
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
@ -26,11 +34,22 @@
|
||||||
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
||||||
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
||||||
import {saveLocalStorage} from "../common/js/utils";
|
import {saveLocalStorage} from "../common/js/utils";
|
||||||
|
import {saveLicense} from "../common/js/utils";
|
||||||
|
import Setting from "@/business/components/settings/router";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
data() {
|
data() {
|
||||||
|
let xpack = false;
|
||||||
|
Setting.children.forEach(child => {
|
||||||
|
if (child.path === "license") {
|
||||||
|
xpack = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
|
valid: xpack,
|
||||||
|
validData: {},
|
||||||
auth: false
|
auth: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -47,6 +66,15 @@
|
||||||
window.location.href = "/login"
|
window.location.href = "/login"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
beforeMount() {
|
||||||
|
if (this.valid === true) {
|
||||||
|
// 验证license
|
||||||
|
this.result = this.$get("/license/valid", response => {
|
||||||
|
this.validData = response.data;
|
||||||
|
saveLicense(response.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {MsLanguageSwitch, MsUser, MsView, MsTopMenus, MsHeaderOrgWs},
|
components: {MsLanguageSwitch, MsUser, MsView, MsTopMenus, MsHeaderOrgWs},
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
|
@ -98,5 +126,13 @@
|
||||||
.align-right {
|
.align-right {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.license-head {
|
||||||
|
height: 30px;
|
||||||
|
background: #BA331B;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,11 @@
|
||||||
methods: {
|
methods: {
|
||||||
setActiveNames(activeNames, item) {
|
setActiveNames(activeNames, item) {
|
||||||
activeNames = [].concat(activeNames);
|
activeNames = [].concat(activeNames);
|
||||||
|
let value = this.accordion ? activeNames[0] : activeNames;
|
||||||
this.activeNames = activeNames;
|
this.activeNames = activeNames;
|
||||||
this.$emit('input', item.name);
|
this.$emit('input', value);
|
||||||
this.$emit('change', item.name);
|
|
||||||
},
|
},
|
||||||
handleItemClick(item) {
|
handleItemCollapseClick(item) {
|
||||||
if (this.accordion) {
|
if (this.accordion) {
|
||||||
this.setActiveNames(
|
this.setActiveNames(
|
||||||
(this.activeNames[0] || this.activeNames[0] === 0) && item.name, item);
|
(this.activeNames[0] || this.activeNames[0] === 0) && item.name, item);
|
||||||
|
@ -59,11 +59,15 @@
|
||||||
}
|
}
|
||||||
this.setActiveNames(activeNames, item);
|
this.setActiveNames(activeNames, item);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handleItemClick(item) {
|
||||||
|
this.$emit('change', item.name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.$on('item-click', this.handleItemClick);
|
this.$on('item-click', this.handleItemClick);
|
||||||
|
this.$on('collapse-click', this.handleItemCollapseClick);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
:aria-expanded="isActive"
|
:aria-expanded="isActive"
|
||||||
:aria-controls="`el-collapse-content-${id}`"
|
:aria-controls="`el-collapse-content-${id}`"
|
||||||
:aria-describedby="`el-collapse-content-${id}`"
|
:aria-describedby="`el-collapse-content-${id}`"
|
||||||
|
@click="handleHeaderClick"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="el-collapse-item__header"
|
class="el-collapse-item__header"
|
||||||
|
@ -20,10 +21,11 @@
|
||||||
@focus="handleFocus"
|
@focus="handleFocus"
|
||||||
@blur="focusing = false"
|
@blur="focusing = false"
|
||||||
>
|
>
|
||||||
<i @click="handleHeaderClick"
|
<div @click.stop="handleCollapseClick">
|
||||||
class="el-collapse-item__arrow el-icon-arrow-right"
|
<i class="el-collapse-item__arrow el-icon-arrow-right"
|
||||||
:class="{'is-active': isActive}">
|
:class="{'is-active': isActive}">
|
||||||
</i>
|
</i>
|
||||||
|
</div>
|
||||||
<slot name="title">{{title}}</slot>
|
<slot name="title">{{title}}</slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -102,6 +104,12 @@
|
||||||
this.focusing = false;
|
this.focusing = false;
|
||||||
this.isClick = true;
|
this.isClick = true;
|
||||||
},
|
},
|
||||||
|
handleCollapseClick() {
|
||||||
|
if (this.disabled) return;
|
||||||
|
this.dispatch('MsApiCollapse', 'collapse-click', this);
|
||||||
|
this.focusing = false;
|
||||||
|
this.isClick = true;
|
||||||
|
},
|
||||||
handleEnterClick() {
|
handleEnterClick() {
|
||||||
this.dispatch('MsApiCollapse', 'item-click', this);
|
this.dispatch('MsApiCollapse', 'item-click', this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,14 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item :label="$t('api_test.request.sql.result_variable')" prop="resultVariable">
|
||||||
|
<el-input v-model="request.resultVariable" maxlength="300" show-word-limit/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item :label="$t('api_test.request.sql.variable_names')" prop="variableNames">
|
||||||
|
<el-input v-model="request.variableNames" maxlength="300" show-word-limit/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<!--<el-form-item :label="'查询类型'" prop="protocol">-->
|
<!--<el-form-item :label="'查询类型'" prop="protocol">-->
|
||||||
<!--<el-select v-model="request.queryType">-->
|
<!--<el-select v-model="request.queryType">-->
|
||||||
<!--<el-option label="dubbo://" :value="protocols.DUBBO"/>-->
|
<!--<el-option label="dubbo://" :value="protocols.DUBBO"/>-->
|
||||||
|
|
|
@ -281,31 +281,16 @@ export class JDBCSampler extends DefaultTestElement {
|
||||||
this.stringProp("dataSource", request.dataSource);
|
this.stringProp("dataSource", request.dataSource);
|
||||||
this.stringProp("query", request.query);
|
this.stringProp("query", request.query);
|
||||||
this.stringProp("queryTimeout", request.queryTimeout);
|
this.stringProp("queryTimeout", request.queryTimeout);
|
||||||
|
this.stringProp("resultVariable", request.resultVariable);
|
||||||
|
this.stringProp("variableNames", request.variableNames);
|
||||||
this.stringProp("queryArguments");
|
this.stringProp("queryArguments");
|
||||||
this.stringProp("queryArgumentsTypes");
|
this.stringProp("queryArgumentsTypes");
|
||||||
this.stringProp("resultSetMaxRows");
|
this.stringProp("resultSetMaxRows");
|
||||||
this.stringProp("resultVariable");
|
|
||||||
this.stringProp("variableNames");
|
|
||||||
this.stringProp("resultSetHandler", 'Store as String');
|
this.stringProp("resultSetHandler", 'Store as String');
|
||||||
this.stringProp("queryType", 'Callable Statement');
|
this.stringProp("queryType", 'Callable Statement');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// <JDBCSampler guiclass="TestBeanGUI" testclass="JDBCSampler" testname="JDBC Request" enabled="true">
|
|
||||||
// <stringProp name="dataSource">test</stringProp>
|
|
||||||
// <stringProp name="query">select id from test_plan;
|
|
||||||
// select name from test_plan;
|
|
||||||
// </stringProp>
|
|
||||||
// <stringProp name="queryArguments"></stringProp>
|
|
||||||
// <stringProp name="queryArgumentsTypes"></stringProp>
|
|
||||||
// <stringProp name="queryTimeout"></stringProp>
|
|
||||||
// <stringProp name="queryType">Callable Statement</stringProp>
|
|
||||||
// <stringProp name="resultSetHandler">Store as String</stringProp>
|
|
||||||
// <stringProp name="resultSetMaxRows"></stringProp>
|
|
||||||
// <stringProp name="resultVariable"></stringProp>
|
|
||||||
// <stringProp name="variableNames"></stringProp>
|
|
||||||
// </JDBCSampler>
|
|
||||||
|
|
||||||
export class HTTPSamplerProxy extends DefaultTestElement {
|
export class HTTPSamplerProxy extends DefaultTestElement {
|
||||||
constructor(testName, options = {}) {
|
constructor(testName, options = {}) {
|
||||||
super('HTTPSamplerProxy', 'HttpTestSampleGui', 'HTTPSamplerProxy', testName);
|
super('HTTPSamplerProxy', 'HttpTestSampleGui', 'HTTPSamplerProxy', testName);
|
||||||
|
|
|
@ -482,6 +482,8 @@ export class SqlRequest extends Request {
|
||||||
this.id = options.id || uuid();
|
this.id = options.id || uuid();
|
||||||
this.name = options.name;
|
this.name = options.name;
|
||||||
this.useEnvironment = options.useEnvironment;
|
this.useEnvironment = options.useEnvironment;
|
||||||
|
this.resultVariable = options.resultVariable;
|
||||||
|
this.variableNames = options.variableNames;
|
||||||
this.debugReport = undefined;
|
this.debugReport = undefined;
|
||||||
this.dataSource = options.dataSource;
|
this.dataSource = options.dataSource;
|
||||||
this.query = options.query;
|
this.query = options.query;
|
||||||
|
@ -1080,7 +1082,7 @@ class JMXGenerator {
|
||||||
|
|
||||||
this.addConstantsTimer(sampler, request);
|
this.addConstantsTimer(sampler, request);
|
||||||
|
|
||||||
if (request.controller.isValid() && request.controller.enable) {
|
if (request.controller && request.controller.isValid() && request.controller.enable) {
|
||||||
if (request.controller instanceof IfController) {
|
if (request.controller instanceof IfController) {
|
||||||
let controller = this.getController(sampler, request);
|
let controller = this.getController(sampler, request);
|
||||||
threadGroup.put(controller);
|
threadGroup.put(controller);
|
||||||
|
@ -1207,7 +1209,7 @@ class JMXGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
addConstantsTimer(sampler, request) {
|
addConstantsTimer(sampler, request) {
|
||||||
if (request.timer.isValid() && request.timer.enable) {
|
if (request.timer && request.timer.isValid() && request.timer.enable) {
|
||||||
sampler.put(new JMXConstantTimer(request.timer.label(), request.timer));
|
sampler.put(new JMXConstantTimer(request.timer.label(), request.timer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
<script>
|
<script>
|
||||||
import {checkoutCurrentOrganization, checkoutCurrentWorkspace} from "@/common/js/utils";
|
import {checkoutCurrentOrganization, checkoutCurrentWorkspace} from "@/common/js/utils";
|
||||||
import Setting from "@/business/components/settings/router";
|
import Setting from "@/business/components/settings/router";
|
||||||
|
import {LicenseKey} from '@/common/js/constants';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsSettingMenu",
|
name: "MsSettingMenu",
|
||||||
|
@ -87,35 +88,35 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
valid() {
|
valid() {
|
||||||
let _this = this;
|
let data = localStorage.getItem(LicenseKey);
|
||||||
this.result = this.$get("/license/valid", response => {
|
if (data != undefined && data != null) {
|
||||||
let data = response.data;
|
data = JSON.parse(data);
|
||||||
if (data === undefined || data === null || data.status != "valid") {
|
}
|
||||||
this.systems.forEach(item => {
|
if (data === undefined || data === null || data.status != "valid") {
|
||||||
if (item.valid != undefined && item.valid === true) {
|
this.systems.forEach(item => {
|
||||||
_this.systems.splice(this.systems.indexOf(item), 1);
|
if (item.valid != undefined && item.valid === true) {
|
||||||
}
|
this.systems.splice(this.systems.indexOf(item), 1);
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.organizations.forEach(item => {
|
this.organizations.forEach(item => {
|
||||||
if (item.valid != undefined && item.valid === true) {
|
if (item.valid != undefined && item.valid === true) {
|
||||||
_this.organizations.splice(this.organizations.indexOf(item), 1);
|
this.organizations.splice(this.organizations.indexOf(item), 1);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.workspaces.forEach(item => {
|
this.workspaces.forEach(item => {
|
||||||
if (item.valid != undefined && item.valid === true) {
|
if (item.valid != undefined && item.valid === true) {
|
||||||
_this.workspaces.splice(this.workspaces.indexOf(item), 1);
|
this.workspaces.splice(this.workspaces.indexOf(item), 1);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.persons.forEach(item => {
|
this.persons.forEach(item => {
|
||||||
if (item.valid != undefined && item.valid === true) {
|
if (item.valid != undefined && item.valid === true) {
|
||||||
_this.persons.splice(this.persons.indexOf(item), 1);
|
this.persons.splice(this.persons.indexOf(item), 1);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
class="ms-switch-project"
|
class="ms-switch-project"
|
||||||
>
|
>
|
||||||
<ms-table-header :condition.sync="condition" @search="initData" title="" :show-create="false"/>
|
<ms-table-header :condition.sync="condition" @search="initData" title="切换项目" :show-create="false"/>
|
||||||
<el-table
|
<el-table
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
<el-col :span="11" :offset="2">
|
<el-col :span="11" :offset="2">
|
||||||
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectIds">
|
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectIds">
|
||||||
<el-select
|
<el-select
|
||||||
:disabled="(form.status == null) ? false : true"
|
|
||||||
v-model="form.projectIds"
|
v-model="form.projectIds"
|
||||||
:placeholder="$t('test_track.plan.input_plan_project')"
|
:placeholder="$t('test_track.plan.input_plan_project')"
|
||||||
multiple
|
multiple
|
||||||
|
@ -175,18 +174,34 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
|
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||||
this.$post('/test/plan/' + this.operationType, param, () => {
|
|
||||||
this.$success(this.$t('commons.save_success'));
|
if (this.operationType === 'edit') {
|
||||||
this.dialogFormVisible = false;
|
this.$confirm('取消项目关联会同时取消该项目下已关联的测试用例', '提示', {
|
||||||
this.$emit("refresh");
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
// 发送广播,刷新 head 上的最新列表
|
cancelButtonText: this.$t('commons.cancel'),
|
||||||
TrackEvent.$emit(LIST_CHANGE);
|
type: 'warning'
|
||||||
});
|
}).then(() => {
|
||||||
|
this.editTestPlan(param);
|
||||||
|
}).catch(() => {
|
||||||
|
this.$info(this.$t('commons.cancel'))
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.editTestPlan(param);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
editTestPlan(param) {
|
||||||
|
this.$post('/test/plan/' + this.operationType, param, () => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.dialogFormVisible = false;
|
||||||
|
this.$emit("refresh");
|
||||||
|
// 发送广播,刷新 head 上的最新列表
|
||||||
|
TrackEvent.$emit(LIST_CHANGE);
|
||||||
|
});
|
||||||
|
},
|
||||||
getProjects() {
|
getProjects() {
|
||||||
this.$get("/project/listAll", (response) => {
|
this.$get("/project/listAll", (response) => {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
:title="operationType === 'edit' ? '编辑用例评审' : '创建用例评审'"
|
:title="operationType === 'edit' ? '编辑用例评审' : '创建用例评审'"
|
||||||
:visible.sync="dialogFormVisible"
|
:visible.sync="dialogFormVisible"
|
||||||
@close="close"
|
@close="close"
|
||||||
|
v-loading="result.loading"
|
||||||
width="65%">
|
width="65%">
|
||||||
|
|
||||||
<el-form :model="form" :rules="rules" ref="reviewForm">
|
<el-form :model="form" :rules="rules" ref="reviewForm">
|
||||||
|
@ -122,6 +123,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dialogFormVisible: false,
|
dialogFormVisible: false,
|
||||||
|
result: {},
|
||||||
form: {
|
form: {
|
||||||
name: '',
|
name: '',
|
||||||
projectIds: [],
|
projectIds: [],
|
||||||
|
@ -187,7 +189,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getProjects() {
|
getProjects() {
|
||||||
this.$get("/project/listAll", (response) => {
|
this.result = this.$get("/project/listAll", (response) => {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
this.projects = response.data;
|
this.projects = response.data;
|
||||||
} else {
|
} else {
|
||||||
|
@ -197,7 +199,7 @@ export default {
|
||||||
},
|
},
|
||||||
setReviewerOptions() {
|
setReviewerOptions() {
|
||||||
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||||
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
this.result = this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||||
this.reviewerOptions = response.data;
|
this.reviewerOptions = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f2d5a342c82e629f510550d5778d752bb73bf5e7
|
Subproject commit 0a375848d034d20eaf05caf11769e1c75c39235c
|
|
@ -1,4 +1,5 @@
|
||||||
export const TokenKey = 'Admin-Token';
|
export const TokenKey = 'Admin-Token';
|
||||||
|
export const LicenseKey = 'License';
|
||||||
export const DEFAULT_LANGUAGE = 'default_language';
|
export const DEFAULT_LANGUAGE = 'default_language';
|
||||||
|
|
||||||
export const ROLE_ADMIN = 'admin';
|
export const ROLE_ADMIN = 'admin';
|
||||||
|
|
|
@ -5,7 +5,8 @@ import {
|
||||||
ROLE_TEST_MANAGER,
|
ROLE_TEST_MANAGER,
|
||||||
ROLE_TEST_USER,
|
ROLE_TEST_USER,
|
||||||
ROLE_TEST_VIEWER,
|
ROLE_TEST_VIEWER,
|
||||||
TokenKey
|
TokenKey,
|
||||||
|
LicenseKey
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
@ -90,6 +91,12 @@ export function saveLocalStorage(response) {
|
||||||
localStorage.setItem("roles", roles);
|
localStorage.setItem("roles", roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function saveLicense(data) {
|
||||||
|
// 保存License
|
||||||
|
localStorage.setItem(LicenseKey, JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function refreshSessionAndCookies(sign, sourceId) {
|
export function refreshSessionAndCookies(sign, sourceId) {
|
||||||
axios.post(REFRESH_SESSION_USER_URL + "/" + sign + "/" + sourceId).then(r => {
|
axios.post(REFRESH_SESSION_USER_URL + "/" + sign + "/" + sourceId).then(r => {
|
||||||
saveLocalStorage(r.data);
|
saveLocalStorage(r.data);
|
||||||
|
@ -175,7 +182,7 @@ export function downloadFile(name, content) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listenGoBack( callback) {
|
export function listenGoBack(callback) {
|
||||||
//监听浏览器返回操作,关闭该对话框
|
//监听浏览器返回操作,关闭该对话框
|
||||||
if (window.history && window.history.pushState) {
|
if (window.history && window.history.pushState) {
|
||||||
history.pushState(null, null, document.URL);
|
history.pushState(null, null, document.URL);
|
||||||
|
@ -189,9 +196,10 @@ export function removeGoBackListener(callback) {
|
||||||
|
|
||||||
export function getUUID() {
|
export function getUUID() {
|
||||||
function S4() {
|
function S4() {
|
||||||
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||||||
}
|
}
|
||||||
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
|
||||||
|
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -551,6 +551,8 @@ export default {
|
||||||
query_timeout: "Max Wait(ms)",
|
query_timeout: "Max Wait(ms)",
|
||||||
name_cannot_be_empty: "SQL request name cannot be empty",
|
name_cannot_be_empty: "SQL request name cannot be empty",
|
||||||
dataSource_cannot_be_empty: "SQL request datasource cannot be empty",
|
dataSource_cannot_be_empty: "SQL request datasource cannot be empty",
|
||||||
|
result_variable: "Result variable",
|
||||||
|
variable_names: "Variable names",
|
||||||
},
|
},
|
||||||
api_import: {
|
api_import: {
|
||||||
label: "Import",
|
label: "Import",
|
||||||
|
|
|
@ -552,6 +552,8 @@ export default {
|
||||||
query_timeout: "最大等待时间(ms)",
|
query_timeout: "最大等待时间(ms)",
|
||||||
name_cannot_be_empty: "SQL请求名称不能为空",
|
name_cannot_be_empty: "SQL请求名称不能为空",
|
||||||
dataSource_cannot_be_empty: "SQL请求数据源不能为空",
|
dataSource_cannot_be_empty: "SQL请求数据源不能为空",
|
||||||
|
result_variable: "存储结果",
|
||||||
|
variable_names: "按列存储",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
api_import: {
|
api_import: {
|
||||||
|
|
|
@ -552,6 +552,8 @@ export default {
|
||||||
query_timeout: "最大等待時間(ms)",
|
query_timeout: "最大等待時間(ms)",
|
||||||
name_cannot_be_empty: "SQL請求名稱不能為空",
|
name_cannot_be_empty: "SQL請求名稱不能為空",
|
||||||
dataSource_cannot_be_empty: "SQL請求數據源不能為空",
|
dataSource_cannot_be_empty: "SQL請求數據源不能為空",
|
||||||
|
result_variable: "存儲結果",
|
||||||
|
variable_names: "按列存儲",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
api_import: {
|
api_import: {
|
||||||
|
|
Loading…
Reference in New Issue