Merge branch 'master' of https://github.com/metersphere/metersphere
# Conflicts: # frontend/src/business/components/api/test/ApiTestConfig.vue
This commit is contained in:
commit
20f89c0017
|
@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -44,6 +45,11 @@ public class APITestController {
|
||||||
return PageUtils.setPageInfo(page, apiTestService.list(request));
|
return PageUtils.setPageInfo(page, apiTestService.list(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/list/ids")
|
||||||
|
public List<ApiTest> listByIds(@RequestBody QueryAPITestRequest request) {
|
||||||
|
return apiTestService.listByIds(request);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/list/{projectId}")
|
@GetMapping("/list/{projectId}")
|
||||||
public List<ApiTest> list(@PathVariable String projectId) {
|
public List<ApiTest> list(@PathVariable String projectId) {
|
||||||
return apiTestService.getApiTestByProjectId(projectId);
|
return apiTestService.getApiTestByProjectId(projectId);
|
||||||
|
@ -91,9 +97,10 @@ public class APITestController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/run/debug", consumes = {"multipart/form-data"})
|
@PostMapping(value = "/run/debug", consumes = {"multipart/form-data"})
|
||||||
public String runDebug(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
public String runDebug(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||||
return apiTestService.runDebug(request, file, bodyFiles);
|
return apiTestService.runDebug(request, file, bodyFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/checkName")
|
@PostMapping(value = "/checkName")
|
||||||
public void checkName(@RequestBody SaveAPITestRequest request) {
|
public void checkName(@RequestBody SaveAPITestRequest request) {
|
||||||
apiTestService.checkName(request);
|
apiTestService.checkName(request);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
||||||
public class QueryAPITestRequest {
|
public class QueryAPITestRequest {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
private String excludeId;
|
||||||
private String projectId;
|
private String projectId;
|
||||||
private String name;
|
private String name;
|
||||||
private String workspaceId;
|
private String workspaceId;
|
||||||
|
@ -19,4 +20,5 @@ public class QueryAPITestRequest {
|
||||||
private List<OrderRequest> orders;
|
private List<OrderRequest> orders;
|
||||||
private Map<String, List<String>> filters;
|
private Map<String, List<String>> filters;
|
||||||
private Map<String, Object> combine;
|
private Map<String, Object> combine;
|
||||||
|
private List<String> ids;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class Scenario {
|
public class Scenario {
|
||||||
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
private String url;
|
private String url;
|
||||||
private String environmentId;
|
private String environmentId;
|
||||||
|
|
|
@ -23,6 +23,8 @@ public class DubboRequest implements Request {
|
||||||
// type 必须放最前面,以便能够转换正确的类
|
// type 必须放最前面,以便能够转换正确的类
|
||||||
private String type = RequestType.DUBBO;
|
private String type = RequestType.DUBBO;
|
||||||
@JSONField(ordinal = 1)
|
@JSONField(ordinal = 1)
|
||||||
|
private String id;
|
||||||
|
@JSONField(ordinal = 1)
|
||||||
private String name;
|
private String name;
|
||||||
@JSONField(ordinal = 2)
|
@JSONField(ordinal = 2)
|
||||||
private String protocol;
|
private String protocol;
|
||||||
|
|
|
@ -20,6 +20,8 @@ public class HttpRequest implements Request {
|
||||||
// type 必须放最前面,以便能够转换正确的类
|
// type 必须放最前面,以便能够转换正确的类
|
||||||
private String type = RequestType.HTTP;
|
private String type = RequestType.HTTP;
|
||||||
@JSONField(ordinal = 1)
|
@JSONField(ordinal = 1)
|
||||||
|
private String id;
|
||||||
|
@JSONField(ordinal = 1)
|
||||||
private String name;
|
private String name;
|
||||||
@JSONField(ordinal = 2)
|
@JSONField(ordinal = 2)
|
||||||
private String url;
|
private String url;
|
||||||
|
|
|
@ -74,12 +74,16 @@ public class APITestService {
|
||||||
return extApiTestMapper.list(request);
|
return extApiTestMapper.list(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ApiTest> listByIds(QueryAPITestRequest request) {
|
||||||
|
return extApiTestMapper.listByIds(request.getIds());
|
||||||
|
}
|
||||||
|
|
||||||
public void create(SaveAPITestRequest request, MultipartFile file, List<MultipartFile> bodyFiles) {
|
public void create(SaveAPITestRequest request, MultipartFile file, List<MultipartFile> bodyFiles) {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw new IllegalArgumentException(Translator.get("file_cannot_be_null"));
|
throw new IllegalArgumentException(Translator.get("file_cannot_be_null"));
|
||||||
}
|
}
|
||||||
checkQuota();
|
checkQuota();
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()) ;
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
ApiTest test = createTest(request);
|
ApiTest test = createTest(request);
|
||||||
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
||||||
|
@ -92,7 +96,7 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
deleteFileByTestId(request.getId());
|
deleteFileByTestId(request.getId());
|
||||||
|
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()) ;
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
ApiTest test = updateTest(request);
|
ApiTest test = updateTest(request);
|
||||||
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
||||||
|
@ -245,6 +249,7 @@ public class APITestService {
|
||||||
MSException.throwException(Translator.get("load_test_already_exists"));
|
MSException.throwException(Translator.get("load_test_already_exists"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkName(SaveAPITestRequest request) {
|
public void checkName(SaveAPITestRequest request) {
|
||||||
ApiTestExample example = new ApiTestExample();
|
ApiTestExample example = new ApiTestExample();
|
||||||
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId());
|
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId());
|
||||||
|
@ -411,7 +416,7 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
updateTest(request);
|
updateTest(request);
|
||||||
APITestResult apiTest = get(request.getId());
|
APITestResult apiTest = get(request.getId());
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()) ;
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
createBodyFiles(apiTest, bodyUploadIds, bodyFiles);
|
createBodyFiles(apiTest, bodyUploadIds, bodyFiles);
|
||||||
if (SessionUtils.getUser() == null) {
|
if (SessionUtils.getUser() == null) {
|
||||||
|
|
|
@ -11,4 +11,6 @@ public interface ExtApiTestMapper {
|
||||||
List<APITestResult> list(@Param("request") QueryAPITestRequest request);
|
List<APITestResult> list(@Param("request") QueryAPITestRequest request);
|
||||||
|
|
||||||
List<ApiTest> getApiTestByProjectId(String projectId);
|
List<ApiTest> getApiTestByProjectId(String projectId);
|
||||||
|
|
||||||
|
List<ApiTest> listByIds(@Param("ids") List<String> ids);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,9 @@
|
||||||
</include>
|
</include>
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
|
<if test="request.excludeId != null">
|
||||||
|
and api_test.id != #{request.excludeId}
|
||||||
|
</if>
|
||||||
<if test="request.name != null">
|
<if test="request.name != null">
|
||||||
and api_test.name like CONCAT('%', #{request.name},'%')
|
and api_test.name like CONCAT('%', #{request.name},'%')
|
||||||
</if>
|
</if>
|
||||||
|
@ -143,4 +146,17 @@
|
||||||
where project_id = #{projectId}
|
where project_id = #{projectId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="listByIds" resultType="io.metersphere.base.domain.ApiTest">
|
||||||
|
select *
|
||||||
|
from api_test
|
||||||
|
<where>
|
||||||
|
<if test="ids != null and ids.size() > 0">
|
||||||
|
id in
|
||||||
|
<foreach collection="ids" item="id" separator="," open="(" close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
|
@ -1 +1 @@
|
||||||
Subproject commit b86032cbbda9a9e6028308aa95a887cff2192f1c
|
Subproject commit ecb30d83c575c6ed14adb1a1ebea389730f410a9
|
|
@ -57,7 +57,8 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-header>
|
</el-header>
|
||||||
<ms-api-scenario-config :debug-report-id="debugReportId" @runDebug="runDebug" :is-read-only="isReadOnly"
|
<ms-api-scenario-config :debug-report-id="debugReportId" @runDebug="runDebug" :is-read-only="isReadOnly"
|
||||||
:scenarios="test.scenarioDefinition" :project-id="test.projectId" ref="config"/>
|
:test-id="test.id" :scenarios="test.scenarioDefinition" :project-id="test.projectId"
|
||||||
|
ref="config"/>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-card>
|
</el-card>
|
||||||
</ms-main-container>
|
</ms-main-container>
|
||||||
|
@ -65,300 +66,334 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
||||||
import {Test} from "./model/ScenarioModel"
|
import {Test, Scenario} from "./model/ScenarioModel"
|
||||||
import MsApiReportStatus from "../report/ApiReportStatus";
|
import MsApiReportStatus from "../report/ApiReportStatus";
|
||||||
import MsApiReportDialog from "./ApiReportDialog";
|
import MsApiReportDialog from "./ApiReportDialog";
|
||||||
import {checkoutTestManagerOrTestUser, downloadFile} from "@/common/js/utils";
|
import {checkoutTestManagerOrTestUser, downloadFile, getUUID} from "@/common/js/utils";
|
||||||
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
|
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
|
||||||
import ApiImport from "./components/import/ApiImport";
|
import ApiImport from "./components/import/ApiImport";
|
||||||
import {getUUID} from "../../../../common/js/utils";
|
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||||
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
||||||
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiTestConfig",
|
name: "MsApiTestConfig",
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
MsMainContainer,
|
MsMainContainer,
|
||||||
MsContainer, ApiImport, MsScheduleConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig
|
MsContainer, ApiImport, MsScheduleConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig
|
||||||
},
|
},
|
||||||
|
|
||||||
props: ["id"],
|
props: ["id"],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
reportVisible: false,
|
reportVisible: false,
|
||||||
create: false,
|
create: false,
|
||||||
result: {},
|
result: {},
|
||||||
projects: [],
|
projects: [],
|
||||||
change: false,
|
change: false,
|
||||||
test: new Test(),
|
test: new Test(),
|
||||||
isReadOnly: false,
|
isReadOnly: false,
|
||||||
debugReportId: ''
|
debugReportId: ''
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
'$route': 'init',
|
|
||||||
test: {
|
|
||||||
handler: function () {
|
|
||||||
this.change = true;
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
let projectId;
|
|
||||||
|
|
||||||
this.isReadOnly = !checkoutTestManagerOrTestUser();
|
|
||||||
|
|
||||||
if (this.id) {
|
|
||||||
this.create = false;
|
|
||||||
this.getTest(this.id);
|
|
||||||
} else {
|
|
||||||
this.create = true;
|
|
||||||
this.test = new Test();
|
|
||||||
if (this.$refs.config) {
|
|
||||||
this.$refs.config.reset();
|
|
||||||
}
|
|
||||||
// 仅创建时获取选择的项目
|
|
||||||
projectId = this.$store.state.common.projectId;
|
|
||||||
}
|
|
||||||
this.result = this.$get("/project/listAll", response => {
|
|
||||||
this.projects = response.data;
|
|
||||||
// 等待项目列表加载完
|
|
||||||
if (projectId) this.test.projectId = projectId;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getTest(id) {
|
|
||||||
this.result = this.$get("/api/get/" + id, response => {
|
|
||||||
if (response.data) {
|
|
||||||
let item = response.data;
|
|
||||||
|
|
||||||
this.test = new Test({
|
|
||||||
id: item.id,
|
|
||||||
projectId: item.projectId,
|
|
||||||
name: item.name,
|
|
||||||
status: item.status,
|
|
||||||
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
|
||||||
schedule: item.schedule ? item.schedule : {},
|
|
||||||
});
|
|
||||||
this.$refs.config.reset();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
save(callback) {
|
|
||||||
let validator = this.test.isValid();
|
|
||||||
if (!validator.isValid) {
|
|
||||||
this.$warning(this.$t(validator.info));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.change = false;
|
|
||||||
let bodyFiles = this.getBodyUploadFiles();
|
|
||||||
let url = this.create ? "/api/create" : "/api/update";
|
|
||||||
let jmx = this.test.toJMX();
|
|
||||||
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
|
||||||
let file = new File([blob], jmx.name);
|
|
||||||
this.result = this.$fileUpload(url, file, bodyFiles, this.test, response => {
|
|
||||||
if (callback) callback();
|
|
||||||
this.create = false;
|
|
||||||
this.resetBodyFile();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveTest() {
|
|
||||||
this.save(() => {
|
|
||||||
this.$success(this.$t('commons.save_success'));
|
|
||||||
if (this.create) {
|
|
||||||
this.$router.push({
|
|
||||||
path: '/api/test/edit?id=' + this.test.id
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 发送广播,刷新 head 上的最新列表
|
|
||||||
ApiEvent.$emit(LIST_CHANGE);
|
|
||||||
})
|
|
||||||
},
|
|
||||||
runTest() {
|
|
||||||
this.result = this.$post("/api/run", {id: this.test.id, triggerMode: 'MANUAL'}, (response) => {
|
|
||||||
this.$success(this.$t('api_test.running'));
|
|
||||||
this.$router.push({
|
|
||||||
path: '/api/report/view/' + response.data
|
|
||||||
})
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveRunTest() {
|
|
||||||
this.change = false;
|
|
||||||
if (!this.validateEnableTest()) {
|
|
||||||
this.$warning(this.$t('api_test.enable_validate_tip'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.save(() => {
|
|
||||||
this.$success(this.$t('commons.save_success'));
|
|
||||||
this.runTest();
|
|
||||||
// 发送广播,刷新 head 上的最新列表
|
|
||||||
ApiEvent.$emit(LIST_CHANGE);
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getBodyUploadFiles() {
|
|
||||||
let bodyUploadFiles = [];
|
|
||||||
this.test.bodyUploadIds = [];
|
|
||||||
this.test.scenarioDefinition.forEach(scenario => {
|
|
||||||
scenario.requests.forEach(request => {
|
|
||||||
if (request.body) {
|
|
||||||
request.body.kvs.forEach(param => {
|
|
||||||
if (param.files) {
|
|
||||||
param.files.forEach(item => {
|
|
||||||
if (item.file) {
|
|
||||||
let fileId = getUUID().substring(0, 8);
|
|
||||||
item.name = item.file.name;
|
|
||||||
item.id = fileId;
|
|
||||||
this.test.bodyUploadIds.push(fileId);
|
|
||||||
bodyUploadFiles.push(item.file);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return bodyUploadFiles;
|
|
||||||
},
|
|
||||||
validateEnableTest() {
|
|
||||||
for (let scenario of this.test.scenarioDefinition) {
|
|
||||||
if (scenario.enable) {
|
|
||||||
for (let request of scenario.requests) {
|
|
||||||
if (request.enable) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
resetBodyFile() {
|
|
||||||
//下次保存不再上传已传文件
|
|
||||||
this.test.scenarioDefinition.forEach(scenario => {
|
|
||||||
scenario.requests.forEach(request => {
|
|
||||||
if (request.body) {
|
|
||||||
request.body.kvs.forEach(param => {
|
|
||||||
if (param.files) {
|
|
||||||
param.files.forEach(item => {
|
|
||||||
if (item.file) {
|
|
||||||
item.file = undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
this.$router.push('/api/test/list/all');
|
|
||||||
},
|
|
||||||
handleCommand(command) {
|
|
||||||
switch (command) {
|
|
||||||
case "report":
|
|
||||||
this.$refs.reportDialog.open();
|
|
||||||
break;
|
|
||||||
case "performance":
|
|
||||||
this.$store.commit('setTest', {
|
|
||||||
projectId: this.test.projectId,
|
|
||||||
name: this.test.name,
|
|
||||||
jmx: this.test.toJMX()
|
|
||||||
})
|
|
||||||
this.$router.push({
|
|
||||||
path: "/performance/test/create"
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case "export":
|
|
||||||
downloadFile(this.test.name + ".json", this.test.export());
|
|
||||||
break;
|
|
||||||
case "import":
|
|
||||||
this.$refs.apiImport.open();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
saveCronExpression(cronExpression) {
|
|
||||||
this.test.schedule.enable = true;
|
|
||||||
this.test.schedule.value = cronExpression;
|
|
||||||
this.saveSchedule();
|
|
||||||
},
|
|
||||||
saveSchedule() {
|
|
||||||
this.checkScheduleEdit();
|
|
||||||
let param = {};
|
|
||||||
param = this.test.schedule;
|
|
||||||
param.resourceId = this.test.id;
|
|
||||||
let url = '/api/schedule/create';
|
|
||||||
if (param.id) {
|
|
||||||
url = '/api/schedule/update';
|
|
||||||
}
|
|
||||||
this.$post(url, param, () => {
|
|
||||||
this.$success(this.$t('commons.save_success'));
|
|
||||||
this.getTest(this.test.id);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
checkScheduleEdit() {
|
|
||||||
if (this.create) {
|
|
||||||
this.$message(this.$t('api_test.environment.please_save_test'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
runDebug(scenario) {
|
|
||||||
if (this.create) {
|
|
||||||
this.$warning(this.$t('api_test.environment.please_save_test'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = "/api/run/debug";
|
|
||||||
let runningTest = new Test();
|
|
||||||
Object.assign(runningTest, this.test);
|
|
||||||
let bodyFiles = this.getBodyUploadFiles();
|
|
||||||
runningTest.scenarioDefinition = [];
|
|
||||||
runningTest.scenarioDefinition.push(scenario);
|
|
||||||
let validator = runningTest.isValid();
|
|
||||||
if (!validator.isValid) {
|
|
||||||
this.$warning(this.$t(validator.info));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let jmx = runningTest.toJMX();
|
|
||||||
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
|
||||||
let file = new File([blob], jmx.name);
|
|
||||||
this.$fileUpload(url, file, bodyFiles, this.test, response => {
|
|
||||||
this.debugReportId = response.data;
|
|
||||||
this.resetBodyFile();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.init();
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
'$route': 'init',
|
||||||
|
test: {
|
||||||
|
handler: function () {
|
||||||
|
this.change = true;
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
let projectId;
|
||||||
|
|
||||||
|
this.isReadOnly = !checkoutTestManagerOrTestUser();
|
||||||
|
|
||||||
|
if (this.id) {
|
||||||
|
this.create = false;
|
||||||
|
this.getTest(this.id);
|
||||||
|
} else {
|
||||||
|
this.create = true;
|
||||||
|
this.test = new Test();
|
||||||
|
if (this.$refs.config) {
|
||||||
|
this.$refs.config.reset();
|
||||||
|
}
|
||||||
|
// 仅创建时获取选择的项目
|
||||||
|
projectId = this.$store.state.common.projectId;
|
||||||
|
}
|
||||||
|
this.result = this.$get("/project/listAll", response => {
|
||||||
|
this.projects = response.data;
|
||||||
|
// 等待项目列表加载完
|
||||||
|
if (projectId) this.test.projectId = projectId;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updateReference() {
|
||||||
|
let updateIds = [];
|
||||||
|
this.test.scenarioDefinition.forEach(scenario => {
|
||||||
|
if (scenario.isReference()) {
|
||||||
|
updateIds.push(scenario.id.split("#")[0]);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (updateIds.length === 0) return;
|
||||||
|
// 更新引用场景
|
||||||
|
this.result = this.$post("/api/list/ids", {ids: updateIds}, response => {
|
||||||
|
let scenarioMap = {};
|
||||||
|
if (response.data) {
|
||||||
|
response.data.forEach(test => {
|
||||||
|
JSON.parse(test.scenarioDefinition).forEach(options => {
|
||||||
|
let referenceId = test.id + "#" + options.id;
|
||||||
|
scenarioMap[referenceId] = new Scenario(options);
|
||||||
|
scenarioMap[referenceId].id = referenceId;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let scenarios = [];
|
||||||
|
this.test.scenarioDefinition.forEach(scenario => {
|
||||||
|
if (scenario.isReference()) {
|
||||||
|
if (scenarioMap[scenario.id]) scenarios.push(scenarioMap[scenario.id]);
|
||||||
|
} else {
|
||||||
|
scenarios.push(scenario);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.test.scenarioDefinition = scenarios;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTest(id) {
|
||||||
|
this.result = this.$get("/api/get/" + id, response => {
|
||||||
|
if (response.data) {
|
||||||
|
let item = response.data;
|
||||||
|
|
||||||
|
this.test = new Test({
|
||||||
|
id: item.id,
|
||||||
|
projectId: item.projectId,
|
||||||
|
name: item.name,
|
||||||
|
status: item.status,
|
||||||
|
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
||||||
|
schedule: item.schedule ? item.schedule : {},
|
||||||
|
});
|
||||||
|
this.updateReference();
|
||||||
|
|
||||||
|
this.$refs.config.reset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
save(callback) {
|
||||||
|
let validator = this.test.isValid();
|
||||||
|
if (!validator.isValid) {
|
||||||
|
this.$warning(this.$t(validator.info));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.change = false;
|
||||||
|
let bodyFiles = this.getBodyUploadFiles();
|
||||||
|
let url = this.create ? "/api/create" : "/api/update";
|
||||||
|
let jmx = this.test.toJMX();
|
||||||
|
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
||||||
|
let file = new File([blob], jmx.name);
|
||||||
|
this.result = this.$fileUpload(url, file, bodyFiles, this.test, () => {
|
||||||
|
if (callback) callback();
|
||||||
|
this.create = false;
|
||||||
|
this.resetBodyFile();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
saveTest() {
|
||||||
|
this.save(() => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
if (this.create) {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/api/test/edit?id=' + this.test.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 发送广播,刷新 head 上的最新列表
|
||||||
|
ApiEvent.$emit(LIST_CHANGE);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
runTest() {
|
||||||
|
this.result = this.$post("/api/run", {id: this.test.id, triggerMode: 'MANUAL'}, (response) => {
|
||||||
|
this.$success(this.$t('api_test.running'));
|
||||||
|
this.$router.push({
|
||||||
|
path: '/api/report/view/' + response.data
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
saveRunTest() {
|
||||||
|
this.change = false;
|
||||||
|
if (!this.validateEnableTest()) {
|
||||||
|
this.$warning(this.$t('api_test.enable_validate_tip'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.save(() => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.runTest();
|
||||||
|
// 发送广播,刷新 head 上的最新列表
|
||||||
|
ApiEvent.$emit(LIST_CHANGE);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getBodyUploadFiles() {
|
||||||
|
let bodyUploadFiles = [];
|
||||||
|
this.test.bodyUploadIds = [];
|
||||||
|
this.test.scenarioDefinition.forEach(scenario => {
|
||||||
|
scenario.requests.forEach(request => {
|
||||||
|
if (request.body) {
|
||||||
|
request.body.kvs.forEach(param => {
|
||||||
|
if (param.files) {
|
||||||
|
param.files.forEach(item => {
|
||||||
|
if (item.file) {
|
||||||
|
let fileId = getUUID().substring(0, 8);
|
||||||
|
item.name = item.file.name;
|
||||||
|
item.id = fileId;
|
||||||
|
this.test.bodyUploadIds.push(fileId);
|
||||||
|
bodyUploadFiles.push(item.file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return bodyUploadFiles;
|
||||||
|
},
|
||||||
|
validateEnableTest() {
|
||||||
|
for (let scenario of this.test.scenarioDefinition) {
|
||||||
|
if (scenario.enable) {
|
||||||
|
for (let request of scenario.requests) {
|
||||||
|
if (request.enable) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
resetBodyFile() {
|
||||||
|
//下次保存不再上传已传文件
|
||||||
|
this.test.scenarioDefinition.forEach(scenario => {
|
||||||
|
scenario.requests.forEach(request => {
|
||||||
|
if (request.body) {
|
||||||
|
request.body.kvs.forEach(param => {
|
||||||
|
if (param.files) {
|
||||||
|
param.files.forEach(item => {
|
||||||
|
if (item.file) {
|
||||||
|
item.file = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$router.push('/api/test/list/all');
|
||||||
|
},
|
||||||
|
handleCommand(command) {
|
||||||
|
switch (command) {
|
||||||
|
case "report":
|
||||||
|
this.$refs.reportDialog.open();
|
||||||
|
break;
|
||||||
|
case "performance":
|
||||||
|
this.$store.commit('setTest', {
|
||||||
|
projectId: this.test.projectId,
|
||||||
|
name: this.test.name,
|
||||||
|
jmx: this.test.toJMX()
|
||||||
|
})
|
||||||
|
this.$router.push({
|
||||||
|
path: "/performance/test/create"
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case "export":
|
||||||
|
downloadFile(this.test.name + ".json", this.test.export());
|
||||||
|
break;
|
||||||
|
case "import":
|
||||||
|
this.$refs.apiImport.open();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveCronExpression(cronExpression) {
|
||||||
|
this.test.schedule.enable = true;
|
||||||
|
this.test.schedule.value = cronExpression;
|
||||||
|
this.saveSchedule();
|
||||||
|
},
|
||||||
|
saveSchedule() {
|
||||||
|
this.checkScheduleEdit();
|
||||||
|
let param = {};
|
||||||
|
param = this.test.schedule;
|
||||||
|
param.resourceId = this.test.id;
|
||||||
|
let url = '/api/schedule/create';
|
||||||
|
if (param.id) {
|
||||||
|
url = '/api/schedule/update';
|
||||||
|
}
|
||||||
|
this.$post(url, param, () => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.getTest(this.test.id);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
checkScheduleEdit() {
|
||||||
|
if (this.create) {
|
||||||
|
this.$message(this.$t('api_test.environment.please_save_test'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
runDebug(scenario) {
|
||||||
|
if (this.create) {
|
||||||
|
this.$warning(this.$t('api_test.environment.please_save_test'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = "/api/run/debug";
|
||||||
|
let runningTest = new Test();
|
||||||
|
Object.assign(runningTest, this.test);
|
||||||
|
let bodyFiles = this.getBodyUploadFiles();
|
||||||
|
runningTest.scenarioDefinition = [];
|
||||||
|
runningTest.scenarioDefinition.push(scenario);
|
||||||
|
let validator = runningTest.isValid();
|
||||||
|
if (!validator.isValid) {
|
||||||
|
this.$warning(this.$t(validator.info));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let jmx = runningTest.toJMX();
|
||||||
|
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
||||||
|
let file = new File([blob], jmx.name);
|
||||||
|
this.$fileUpload(url, file, bodyFiles, this.test, response => {
|
||||||
|
this.debugReportId = response.data;
|
||||||
|
this.resetBodyFile();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.init();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.test-container {
|
.test-container {
|
||||||
height: calc(100vh - 155px);
|
height: calc(100vh - 155px);
|
||||||
min-height: 600px;
|
min-height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.test-name {
|
.test-name {
|
||||||
width: 600px;
|
width: 600px;
|
||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.test-project {
|
.test-project {
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.test-container .more {
|
.test-container .more {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,44 +8,60 @@
|
||||||
:title="scenario.name" :name="index" :class="{'disable-scenario': !scenario.enable}">
|
:title="scenario.name" :name="index" :class="{'disable-scenario': !scenario.enable}">
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<div class="scenario-name">
|
<div class="scenario-name">
|
||||||
{{scenario.name}}
|
<el-tag type="info" size="small" v-if="scenario.isReference()">{{
|
||||||
|
$t('api_test.scenario.reference')
|
||||||
|
}}
|
||||||
|
</el-tag>
|
||||||
|
{{ scenario.name }}
|
||||||
<span id="hint" v-if="!scenario.name">
|
<span id="hint" v-if="!scenario.name">
|
||||||
{{$t('api_test.scenario.config')}}
|
{{ $t('api_test.scenario.config') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<el-dropdown trigger="click" @command="handleCommand">
|
<el-dropdown trigger="click" @command="handleCommand">
|
||||||
<span class="el-dropdown-link el-icon-more scenario-btn"/>
|
<span class="el-dropdown-link el-icon-more scenario-btn"/>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item :disabled="isReadOnly" :command="{type: 'copy', index: index}">
|
<el-dropdown-item :disabled="isReadOnly" :command="{type: 'copy', index: index}">
|
||||||
{{$t('api_test.scenario.copy')}}
|
{{ $t('api_test.scenario.copy') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item :disabled="isReadOnly" :command="{type:'delete', index:index}">
|
<el-dropdown-item :disabled="isReadOnly" :command="{type:'delete', index:index}">
|
||||||
{{$t('api_test.scenario.delete')}}
|
{{ $t('api_test.scenario.delete') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item v-if="scenario.enable" :disabled="isReadOnly" :command="{type:'disable', index:index}">
|
<el-dropdown-item v-if="scenario.enable" :disabled="isReadOnly"
|
||||||
{{$t('api_test.scenario.disable')}}
|
:command="{type:'disable', index:index}">
|
||||||
|
{{ $t('api_test.scenario.disable') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item v-if="!scenario.enable" :disabled="isReadOnly" :command="{type:'enable', index:index}">
|
<el-dropdown-item v-if="!scenario.enable" :disabled="isReadOnly"
|
||||||
{{$t('api_test.scenario.enable')}}
|
:command="{type:'enable', index:index}">
|
||||||
|
{{ $t('api_test.scenario.enable') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
<ms-api-request-config :is-read-only="isReadOnly" :scenario="scenario" @select="select"/>
|
<ms-api-request-config :is-read-only="disable" :scenario="scenario" @select="select"/>
|
||||||
</ms-api-collapse-item>
|
</ms-api-collapse-item>
|
||||||
</draggable>
|
</draggable>
|
||||||
</ms-api-collapse>
|
</ms-api-collapse>
|
||||||
</div>
|
</div>
|
||||||
<el-button :disabled="isReadOnly" class="scenario-create" type="primary" size="mini" icon="el-icon-plus" plain @click="createScenario"/>
|
<el-popover placement="top" v-model="visible">
|
||||||
|
<el-radio-group v-model="type" @change="createScenario">
|
||||||
|
<el-radio :label="types.CREATE">{{ $t('api_test.scenario.create_scenario') }}</el-radio>
|
||||||
|
<el-radio :label="types.SELECT">{{ $t('api_test.scenario.select_scenario') }}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-button slot="reference" :disabled="isReadOnly" class="scenario-create" type="primary" size="mini"
|
||||||
|
icon="el-icon-plus" plain/>
|
||||||
|
</el-popover>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
|
||||||
<el-main class="scenario-main">
|
<el-main class="scenario-main">
|
||||||
<div class="scenario-form">
|
<div class="scenario-form">
|
||||||
<ms-api-scenario-form :is-read-only="isReadOnly" :scenario="selected" :project-id="projectId" v-if="isScenario"/>
|
<ms-api-scenario-form :is-read-only="disable" :scenario="selected" :project-id="projectId"
|
||||||
<ms-api-request-form :debug-report-id="debugReportId" @runDebug="runDebug" :is-read-only="isReadOnly"
|
v-if="isScenario"/>
|
||||||
|
<ms-api-request-form :debug-report-id="debugReportId" @runDebug="runDebug"
|
||||||
|
:is-read-only="disable"
|
||||||
:request="selected" :scenario="currentScenario" v-if="isRequest"/>
|
:request="selected" :scenario="currentScenario" v-if="isRequest"/>
|
||||||
</div>
|
</div>
|
||||||
</el-main>
|
</el-main>
|
||||||
|
<ms-api-scenario-select :exclude-id="testId" @select="selectScenario" ref="selectDialog"/>
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -58,11 +74,13 @@ import MsApiRequestForm from "./request/ApiRequestForm";
|
||||||
import MsApiScenarioForm from "./ApiScenarioForm";
|
import MsApiScenarioForm from "./ApiScenarioForm";
|
||||||
import {Request, Scenario} from "../model/ScenarioModel";
|
import {Request, Scenario} from "../model/ScenarioModel";
|
||||||
import draggable from 'vuedraggable';
|
import draggable from 'vuedraggable';
|
||||||
|
import MsApiScenarioSelect from "@/business/components/api/test/components/ApiScenarioSelect";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiScenarioConfig",
|
name: "MsApiScenarioConfig",
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
|
MsApiScenarioSelect,
|
||||||
MsApiRequestConfig,
|
MsApiRequestConfig,
|
||||||
MsApiScenarioForm,
|
MsApiScenarioForm,
|
||||||
MsApiRequestForm,
|
MsApiRequestForm,
|
||||||
|
@ -71,202 +89,237 @@ export default {
|
||||||
draggable
|
draggable
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
scenarios: Array,
|
testId: String,
|
||||||
projectId: String,
|
scenarios: Array,
|
||||||
isReadOnly: {
|
projectId: String,
|
||||||
type: Boolean,
|
isReadOnly: {
|
||||||
default: false
|
type: Boolean,
|
||||||
},
|
default: false
|
||||||
debugReportId: String
|
|
||||||
},
|
},
|
||||||
|
debugReportId: String,
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeName: 0,
|
visible: false,
|
||||||
selected: [Scenario, Request],
|
types: {CREATE: "create", SELECT: "select"},
|
||||||
currentScenario: {}
|
type: "",
|
||||||
}
|
activeName: 0,
|
||||||
},
|
selected: [Scenario, Request],
|
||||||
|
currentScenario: {}
|
||||||
watch: {
|
|
||||||
projectId() {
|
|
||||||
this.initScenarioEnvironment();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
activated() {
|
|
||||||
this.initScenarioEnvironment();
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
createScenario: function () {
|
|
||||||
this.scenarios.push(new Scenario());
|
|
||||||
},
|
|
||||||
copyScenario: function (index) {
|
|
||||||
let scenario = this.scenarios[index];
|
|
||||||
this.scenarios.push(new Scenario(scenario));
|
|
||||||
},
|
|
||||||
deleteScenario: function (index) {
|
|
||||||
this.scenarios.splice(index, 1);
|
|
||||||
if (this.scenarios.length === 0) {
|
|
||||||
this.createScenario();
|
|
||||||
this.select(this.scenarios[0]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
disableScenario: function (index) {
|
|
||||||
this.scenarios[index].enable = false;
|
|
||||||
},
|
|
||||||
enableScenario: function (index) {
|
|
||||||
this.scenarios[index].enable = true;
|
|
||||||
},
|
|
||||||
handleChange: function (index) {
|
|
||||||
this.select(this.scenarios[index]);
|
|
||||||
},
|
|
||||||
handleCommand: function (command) {
|
|
||||||
switch (command.type) {
|
|
||||||
case "copy":
|
|
||||||
this.copyScenario(command.index);
|
|
||||||
break;
|
|
||||||
case "delete":
|
|
||||||
this.deleteScenario(command.index);
|
|
||||||
break;
|
|
||||||
case "disable":
|
|
||||||
this.disableScenario(command.index);
|
|
||||||
break;
|
|
||||||
case "enable":
|
|
||||||
this.enableScenario(command.index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
select: function (obj, scenario) {
|
|
||||||
this.selected = null;
|
|
||||||
this.$nextTick(function () {
|
|
||||||
if (obj instanceof Scenario) {
|
|
||||||
this.currentScenario = obj;
|
|
||||||
} else {
|
|
||||||
this.currentScenario = scenario;
|
|
||||||
}
|
|
||||||
this.selected = obj;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
reset: function () {
|
|
||||||
this.$nextTick(function () {
|
|
||||||
this.activeName = 0;
|
|
||||||
this.select(this.scenarios[0]);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
initScenarioEnvironment: function () {
|
|
||||||
if (this.projectId) {
|
|
||||||
this.result = this.$get('/api/environment/list/' + this.projectId, response => {
|
|
||||||
let environments = response.data;
|
|
||||||
let environmentMap = new Map();
|
|
||||||
environments.forEach(environment => {
|
|
||||||
environmentMap.set(environment.id, environment);
|
|
||||||
});
|
|
||||||
this.scenarios.forEach(scenario => {
|
|
||||||
if (scenario.environmentId) {
|
|
||||||
let env = environmentMap.get(scenario.environmentId);
|
|
||||||
if (!env) {
|
|
||||||
scenario.environmentId = undefined;
|
|
||||||
} else {
|
|
||||||
scenario.environment = env;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
runDebug(request) {
|
|
||||||
let scenario = new Scenario();
|
|
||||||
Object.assign(scenario, this.currentScenario);
|
|
||||||
scenario.requests = [];
|
|
||||||
scenario.requests.push(request);
|
|
||||||
this.$emit('runDebug', scenario);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
isScenario() {
|
|
||||||
return this.selected instanceof Scenario;
|
|
||||||
},
|
|
||||||
isRequest() {
|
|
||||||
return this.selected instanceof Request;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.select(this.scenarios[0]);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
projectId() {
|
||||||
|
this.initScenarioEnvironment();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
activated() {
|
||||||
|
this.initScenarioEnvironment();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
notContainsScenario(item) {
|
||||||
|
for (let scenario of this.scenarios) {
|
||||||
|
if (item.id === scenario.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
selectScenario(selection) {
|
||||||
|
selection.filter(this.notContainsScenario).forEach(item => {
|
||||||
|
this.scenarios.push(item);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
createScenario() {
|
||||||
|
if (this.type === this.types.CREATE) {
|
||||||
|
this.scenarios.push(new Scenario());
|
||||||
|
} else {
|
||||||
|
this.$refs.selectDialog.open();
|
||||||
|
}
|
||||||
|
this.visible = false;
|
||||||
|
this.type = "";
|
||||||
|
},
|
||||||
|
copyScenario(index) {
|
||||||
|
let scenario = this.scenarios[index];
|
||||||
|
this.scenarios.push(scenario.clone());
|
||||||
|
},
|
||||||
|
deleteScenario(index) {
|
||||||
|
this.scenarios.splice(index, 1);
|
||||||
|
if (this.scenarios.length === 0) {
|
||||||
|
this.createScenario();
|
||||||
|
this.select(this.scenarios[0]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disableScenario(index) {
|
||||||
|
this.scenarios[index].enable = false;
|
||||||
|
},
|
||||||
|
enableScenario(index) {
|
||||||
|
this.scenarios[index].enable = true;
|
||||||
|
},
|
||||||
|
handleChange(index) {
|
||||||
|
this.select(this.scenarios[index]);
|
||||||
|
},
|
||||||
|
handleCommand(command) {
|
||||||
|
switch (command.type) {
|
||||||
|
case "copy":
|
||||||
|
this.copyScenario(command.index);
|
||||||
|
break;
|
||||||
|
case "delete":
|
||||||
|
this.deleteScenario(command.index);
|
||||||
|
break;
|
||||||
|
case "disable":
|
||||||
|
this.disableScenario(command.index);
|
||||||
|
break;
|
||||||
|
case "enable":
|
||||||
|
this.enableScenario(command.index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
select(obj, scenario) {
|
||||||
|
this.selected = null;
|
||||||
|
this.$nextTick(function () {
|
||||||
|
if (obj instanceof Scenario) {
|
||||||
|
this.currentScenario = obj;
|
||||||
|
} else {
|
||||||
|
this.currentScenario = scenario;
|
||||||
|
}
|
||||||
|
this.selected = obj;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
this.$nextTick(function () {
|
||||||
|
this.activeName = 0;
|
||||||
|
this.select(this.scenarios[0]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
initScenarioEnvironment() {
|
||||||
|
if (this.projectId) {
|
||||||
|
this.result = this.$get('/api/environment/list/' + this.projectId, response => {
|
||||||
|
let environments = response.data;
|
||||||
|
let environmentMap = new Map();
|
||||||
|
environments.forEach(environment => {
|
||||||
|
environmentMap.set(environment.id, environment);
|
||||||
|
});
|
||||||
|
this.scenarios.forEach(scenario => {
|
||||||
|
if (scenario.environmentId) {
|
||||||
|
let env = environmentMap.get(scenario.environmentId);
|
||||||
|
if (!env) {
|
||||||
|
scenario.environmentId = undefined;
|
||||||
|
} else {
|
||||||
|
scenario.environment = env;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
runDebug(request) {
|
||||||
|
let scenario = new Scenario();
|
||||||
|
Object.assign(scenario, this.currentScenario);
|
||||||
|
scenario.requests = [];
|
||||||
|
scenario.requests.push(request);
|
||||||
|
this.$emit('runDebug', scenario);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
isScenario() {
|
||||||
|
return this.selected instanceof Scenario;
|
||||||
|
},
|
||||||
|
isRequest() {
|
||||||
|
return this.selected instanceof Request;
|
||||||
|
},
|
||||||
|
isReference() {
|
||||||
|
if (this.selected instanceof Scenario) {
|
||||||
|
return this.selected.isReference();
|
||||||
|
}
|
||||||
|
if (this.selected instanceof Request) {
|
||||||
|
return this.currentScenario.isReference();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
disable() {
|
||||||
|
return this.isReadOnly || this.isReference;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.select(this.scenarios[0]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.scenario-aside {
|
.scenario-aside {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #EBEEF5;
|
border: 1px solid #EBEEF5;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenario-list {
|
.scenario-list {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 28px;
|
bottom: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenario-name {
|
.scenario-name {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.scenario-name > #hint {*/
|
/*.scenario-name > #hint {*/
|
||||||
/*color: #8a8b8d;*/
|
/*color: #8a8b8d;*/
|
||||||
/*}*/
|
/*}*/
|
||||||
|
|
||||||
.scenario-btn {
|
.scenario-btn {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 13px;
|
padding: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenario-create {
|
.scenario-create {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenario-main {
|
.scenario-main {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
border: 1px solid #EBEEF5;
|
border: 1px solid #EBEEF5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenario-form {
|
.scenario-form {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenario-ghost {
|
.scenario-ghost {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenario-draggable {
|
.scenario-draggable {
|
||||||
background-color: #909399;
|
background-color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disable-scenario >>> .el-collapse-item__header {
|
.disable-scenario >>> .el-collapse-item__header {
|
||||||
border-right: 2px solid #909399;
|
border-right: 2px solid #909399;
|
||||||
color: #8a8b8d;
|
color: #8a8b8d;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form :model="scenario" :rules="rules" ref="scenario" label-width="100px" v-loading="result.loading">
|
<el-form :model="scenario" :rules="rules" ref="scenario" label-width="100px" v-loading="result.loading"
|
||||||
|
:disabled="isReadOnly">
|
||||||
<el-form-item :label="$t('api_test.scenario.name')" prop="name">
|
<el-form-item :label="$t('api_test.scenario.name')" prop="name">
|
||||||
<el-input :disabled="isReadOnly" v-model="scenario.name" maxlength="100" show-word-limit/>
|
<el-input :disabled="isReadOnly" v-model="scenario.name" maxlength="100" show-word-limit/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -26,7 +27,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-tabs v-model="activeName">
|
<el-tabs v-model="activeName" :disabled="isReadOnly">
|
||||||
<el-tab-pane :label="$t('api_test.scenario.variables')" name="parameters">
|
<el-tab-pane :label="$t('api_test.scenario.variables')" name="parameters">
|
||||||
<ms-api-scenario-variables :is-read-only="isReadOnly" :items="scenario.variables"
|
<ms-api-scenario-variables :is-read-only="isReadOnly" :items="scenario.variables"
|
||||||
:description="$t('api_test.scenario.kv_description')"/>
|
:description="$t('api_test.scenario.kv_description')"/>
|
||||||
|
@ -38,11 +39,11 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('api_test.scenario.dubbo')" name="dubbo">
|
<el-tab-pane :label="$t('api_test.scenario.dubbo')" name="dubbo">
|
||||||
<div class="dubbo-config-title">Config Center</div>
|
<div class="dubbo-config-title">Config Center</div>
|
||||||
<ms-dubbo-config-center :config="scenario.dubboConfig.configCenter"/>
|
<ms-dubbo-config-center :config="scenario.dubboConfig.configCenter" :is-read-only="isReadOnly"/>
|
||||||
<div class="dubbo-config-title">Registry Center</div>
|
<div class="dubbo-config-title">Registry Center</div>
|
||||||
<ms-dubbo-registry-center :registry="scenario.dubboConfig.registryCenter"/>
|
<ms-dubbo-registry-center :registry="scenario.dubboConfig.registryCenter" :is-read-only="isReadOnly"/>
|
||||||
<div class="dubbo-config-title">Consumer & Service</div>
|
<div class="dubbo-config-title">Consumer & Service</div>
|
||||||
<ms-dubbo-consumer-service :consumer="scenario.dubboConfig.consumerAndService"/>
|
<ms-dubbo-consumer-service :consumer="scenario.dubboConfig.consumerAndService" :is-read-only="isReadOnly"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog :title="$t('api_test.scenario.select_scenario')" :visible.sync="visible" width="70%">
|
||||||
|
<el-table stripe :data="tableData" size="small" @expand-change="expand">
|
||||||
|
<el-table-column type="expand" width="50">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<ms-api-scenario-select-sub-table :row="row" v-model="row.selected"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="name" :label="$t('api_test.scenario.test_name')" width="400" show-overflow-tooltip/>
|
||||||
|
<el-table-column prop="sr" :label="$t('api_test.scenario.scenario_request')" width="150" show-overflow-tooltip/>
|
||||||
|
<el-table-column prop="userName" :label="$t('api_test.creator')" width="150" show-overflow-tooltip/>
|
||||||
|
<el-table-column prop="enable" :label="$t('api_test.scenario.enable_disable')" width="150"/>
|
||||||
|
<el-table-column>
|
||||||
|
<template v-slot:header>
|
||||||
|
<div class="search-header">
|
||||||
|
<ms-table-search-bar :condition.sync="condition" @change="search" class="search-bar"
|
||||||
|
:tip="$t('commons.search_by_name')"/>
|
||||||
|
<ms-table-adv-search-bar :condition.sync="condition" @search="search"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
{{ row.reference }}
|
||||||
|
<el-button type="text" size="small" @click="reference(row)">
|
||||||
|
{{ $t('api_test.scenario.reference') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" size="small" @click="clone(row)">{{ $t('api_test.scenario.clone') }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total"/>
|
||||||
|
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="close">{{ $t('commons.cancel') }}</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
|
||||||
|
import {TEST_CONFIGS} from "@/business/components/common/components/search/search-components";
|
||||||
|
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||||
|
import MsTableSearchBar from "@/business/components/common/components/MsTableSearchBar";
|
||||||
|
import MsTableAdvSearchBar from "@/business/components/common/components/search/MsTableAdvSearchBar";
|
||||||
|
import MsApiScenarioSelectSubTable from "@/business/components/api/test/components/ApiScenarioSelectSubTable";
|
||||||
|
import {Scenario} from "@/business/components/api/test/model/ScenarioModel";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsApiScenarioSelect",
|
||||||
|
components: {
|
||||||
|
MsApiScenarioSelectSubTable,
|
||||||
|
MsTableAdvSearchBar, MsTableSearchBar, MsTablePagination, MsTableHeader
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
excludeId: String
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
condition: {
|
||||||
|
components: TEST_CONFIGS
|
||||||
|
},
|
||||||
|
tableData: [],
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 5,
|
||||||
|
total: 0,
|
||||||
|
selection: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
search() {
|
||||||
|
this.condition.excludeId = this.excludeId;
|
||||||
|
let url = "/api/list/" + this.currentPage + "/" + this.pageSize;
|
||||||
|
this.result = this.$post(url, this.condition, response => {
|
||||||
|
let data = response.data;
|
||||||
|
this.total = data.itemCount;
|
||||||
|
this.tableData = data.listObject;
|
||||||
|
this.tableData.forEach(row => {
|
||||||
|
row.selected = [];
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reference(row) {
|
||||||
|
let scenarios = [];
|
||||||
|
for (let options of row.selected) {
|
||||||
|
if (!options.id) {
|
||||||
|
this.$warning(this.$t('api_test.scenario.cant_reference'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let scenario = new Scenario(options);
|
||||||
|
if (!scenario.isReference()) {
|
||||||
|
scenario.id = row.id + "#" + options.id;
|
||||||
|
} else {
|
||||||
|
scenario.id = options.id;
|
||||||
|
}
|
||||||
|
scenarios.push(scenario);
|
||||||
|
}
|
||||||
|
this.$emit('select', scenarios);
|
||||||
|
},
|
||||||
|
clone(row) {
|
||||||
|
let scenarios = [];
|
||||||
|
row.selected.forEach(options => {
|
||||||
|
scenarios.push(new Scenario(options));
|
||||||
|
})
|
||||||
|
this.$emit('select', scenarios);
|
||||||
|
},
|
||||||
|
open() {
|
||||||
|
this.search();
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
expand(row) {
|
||||||
|
row.selected = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.search-header {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
width: 200px
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,58 @@
|
||||||
|
<template>
|
||||||
|
<el-table stripe :data="scenarios" class="adjust-table" @select-all="select" @select="select" size="small"
|
||||||
|
:show-header="false" ref="table" v-loading="result.loading">
|
||||||
|
<el-table-column type="selection" width="50"/>
|
||||||
|
<el-table-column prop="name" width="350" show-overflow-tooltip/>
|
||||||
|
<el-table-column width="150">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
1 / {{ row.requests.length }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="null" width="150">
|
||||||
|
{{ row.userName }}
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="enable">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<el-tag type="success" size="small" v-if="row.enable !== false">{{ $t('api_test.scenario.enable') }}</el-tag>
|
||||||
|
<el-tag type="info" size="small" v-else>{{ $t('api_test.scenario.disable') }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column/>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsApiScenarioSelectSubTable",
|
||||||
|
props: {
|
||||||
|
row: Object
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: {loading: true},
|
||||||
|
scenarios: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getTest() {
|
||||||
|
this.result = this.$get("/api/get/" + this.row.id, response => {
|
||||||
|
if (response.data) {
|
||||||
|
this.scenarios = JSON.parse(response.data.scenarioDefinition);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
select(selection) {
|
||||||
|
this.$emit('input', selection);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form :model="request" :rules="rules" ref="request" label-width="100px">
|
<el-form :model="request" :rules="rules" ref="request" label-width="100px" :disabled="isReadOnly">
|
||||||
|
|
||||||
<el-form-item :label="$t('api_test.request.name')" prop="name">
|
<el-form-item :label="$t('api_test.request.name')" prop="name">
|
||||||
<el-input :disabled="isReadOnly" v-model="request.name" maxlength="300" show-word-limit/>
|
<el-input :disabled="isReadOnly" v-model="request.name" maxlength="300" show-word-limit/>
|
||||||
|
@ -41,7 +41,9 @@
|
||||||
<el-checkbox class="follow-redirects-item" v-model="request.followRedirects">{{$t('api_test.request.follow_redirects')}}</el-checkbox>
|
<el-checkbox class="follow-redirects-item" v-model="request.followRedirects">{{$t('api_test.request.follow_redirects')}}</el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-button :disabled="!request.enable || !scenario.enable || isReadOnly" class="debug-button" size="small" type="primary" @click="runDebug">{{ $t('api_test.request.debug') }}</el-button>
|
<el-button :disabled="!request.enable || !scenario.enable || isReadOnly" class="debug-button" size="small"
|
||||||
|
type="primary" @click="runDebug">{{ $t('api_test.request.debug') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
<el-tabs v-model="activeName">
|
<el-tabs v-model="activeName">
|
||||||
<el-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
<el-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
||||||
|
|
|
@ -106,7 +106,6 @@ export class BaseConfig {
|
||||||
|
|
||||||
set(options) {
|
set(options) {
|
||||||
options = this.initOptions(options)
|
options = this.initOptions(options)
|
||||||
|
|
||||||
for (let name in options) {
|
for (let name in options) {
|
||||||
if (options.hasOwnProperty(name)) {
|
if (options.hasOwnProperty(name)) {
|
||||||
if (!(this[name] instanceof Array)) {
|
if (!(this[name] instanceof Array)) {
|
||||||
|
@ -142,7 +141,7 @@ export class Test extends BaseConfig {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super();
|
||||||
this.type = "MS API CONFIG";
|
this.type = "MS API CONFIG";
|
||||||
this.version = '1.1.0';
|
this.version = '1.3.0';
|
||||||
this.id = uuid();
|
this.id = uuid();
|
||||||
this.name = undefined;
|
this.name = undefined;
|
||||||
this.projectId = undefined;
|
this.projectId = undefined;
|
||||||
|
@ -201,6 +200,7 @@ export class Test extends BaseConfig {
|
||||||
export class Scenario extends BaseConfig {
|
export class Scenario extends BaseConfig {
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super();
|
super();
|
||||||
|
this.id = undefined;
|
||||||
this.name = undefined;
|
this.name = undefined;
|
||||||
this.url = undefined;
|
this.url = undefined;
|
||||||
this.variables = [];
|
this.variables = [];
|
||||||
|
@ -216,15 +216,17 @@ export class Scenario extends BaseConfig {
|
||||||
this.sets({variables: KeyValue, headers: KeyValue, requests: RequestFactory}, options);
|
this.sets({variables: KeyValue, headers: KeyValue, requests: RequestFactory}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
initOptions(options) {
|
initOptions(options = {}) {
|
||||||
options = options || {};
|
options.id = options.id || uuid();
|
||||||
options.requests = options.requests || [new RequestFactory()];
|
options.requests = options.requests || [new RequestFactory()];
|
||||||
options.dubboConfig = new DubboConfig(options.dubboConfig);
|
options.dubboConfig = new DubboConfig(options.dubboConfig);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
clone() {
|
clone() {
|
||||||
return new Scenario(this);
|
let clone = new Scenario(this);
|
||||||
|
clone.id = uuid();
|
||||||
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
isValid() {
|
isValid() {
|
||||||
|
@ -238,6 +240,10 @@ export class Scenario extends BaseConfig {
|
||||||
}
|
}
|
||||||
return {isValid: true};
|
return {isValid: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReference() {
|
||||||
|
return this.id.indexOf("#") !== -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DubboConfig extends BaseConfig {
|
class DubboConfig extends BaseConfig {
|
||||||
|
@ -296,6 +302,7 @@ export class Request extends BaseConfig {
|
||||||
export class HttpRequest extends Request {
|
export class HttpRequest extends Request {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(RequestFactory.TYPES.HTTP);
|
super(RequestFactory.TYPES.HTTP);
|
||||||
|
this.id = undefined;
|
||||||
this.name = undefined;
|
this.name = undefined;
|
||||||
this.url = undefined;
|
this.url = undefined;
|
||||||
this.path = undefined;
|
this.path = undefined;
|
||||||
|
@ -321,8 +328,8 @@ export class HttpRequest extends Request {
|
||||||
this.sets({parameters: KeyValue, headers: KeyValue}, options);
|
this.sets({parameters: KeyValue, headers: KeyValue}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
initOptions(options) {
|
initOptions(options = {}) {
|
||||||
options = options || {};
|
options.id = options.id || uuid();
|
||||||
options.method = options.method || "GET";
|
options.method = options.method || "GET";
|
||||||
options.body = new Body(options.body);
|
options.body = new Body(options.body);
|
||||||
options.assertions = new Assertions(options.assertions);
|
options.assertions = new Assertions(options.assertions);
|
||||||
|
@ -381,6 +388,7 @@ export class DubboRequest extends Request {
|
||||||
|
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super(RequestFactory.TYPES.DUBBO);
|
super(RequestFactory.TYPES.DUBBO);
|
||||||
|
this.id = options.id || uuid();
|
||||||
this.name = options.name;
|
this.name = options.name;
|
||||||
this.protocol = options.protocol || DubboRequest.PROTOCOLS.DUBBO;
|
this.protocol = options.protocol || DubboRequest.PROTOCOLS.DUBBO;
|
||||||
this.interface = options.interface;
|
this.interface = options.interface;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7e4d80cc2b870a8cac6dbb9fe6711ab6041faf6d
|
Subproject commit 390943d21e7d0196e0d7d5faa66f0131cb631614
|
|
@ -414,7 +414,15 @@ export default {
|
||||||
copy: "Copy scenario",
|
copy: "Copy scenario",
|
||||||
delete: "Delete scenario",
|
delete: "Delete scenario",
|
||||||
disable: "Disable",
|
disable: "Disable",
|
||||||
enable: "Enable"
|
enable: "Enable",
|
||||||
|
create_scenario: "Create scenario",
|
||||||
|
select_scenario: "Select scenario",
|
||||||
|
scenario_request: "Scenario/Request",
|
||||||
|
enable_disable: "Enable/Disable",
|
||||||
|
test_name: "Test Name",
|
||||||
|
reference: "Reference",
|
||||||
|
clone: "Copy",
|
||||||
|
cant_reference:'Historical test files, can be referenced after re-saving'
|
||||||
},
|
},
|
||||||
request: {
|
request: {
|
||||||
debug: "Debug",
|
debug: "Debug",
|
||||||
|
@ -484,7 +492,7 @@ export default {
|
||||||
xpath_expression: "XPath expression",
|
xpath_expression: "XPath expression",
|
||||||
},
|
},
|
||||||
processor: {
|
processor: {
|
||||||
pre_exec_script : "PreProcessor",
|
pre_exec_script: "PreProcessor",
|
||||||
post_exec_script: "PostProcessor",
|
post_exec_script: "PostProcessor",
|
||||||
code_template: "Code template",
|
code_template: "Code template",
|
||||||
bean_shell_processor_tip: "Currently only BeanShell scripts are supported",
|
bean_shell_processor_tip: "Currently only BeanShell scripts are supported",
|
||||||
|
@ -716,7 +724,7 @@ export default {
|
||||||
result_distribution: "Result distribution",
|
result_distribution: "Result distribution",
|
||||||
custom_component: "Custom",
|
custom_component: "Custom",
|
||||||
create_report: "Create report",
|
create_report: "Create report",
|
||||||
defect_list:"Defect list",
|
defect_list: "Defect list",
|
||||||
view_report: "View report",
|
view_report: "View report",
|
||||||
component_library: "Component library",
|
component_library: "Component library",
|
||||||
component_library_tip: "Drag and drop the component from the component library, add to the right, preview the report effect, only one can be added per system component.",
|
component_library_tip: "Drag and drop the component from the component library, add to the right, preview the report effect, only one can be added per system component.",
|
||||||
|
|
|
@ -414,7 +414,15 @@ export default {
|
||||||
copy: "复制场景",
|
copy: "复制场景",
|
||||||
delete: "删除场景",
|
delete: "删除场景",
|
||||||
disable: "禁用",
|
disable: "禁用",
|
||||||
enable: "启用"
|
enable: "启用",
|
||||||
|
create_scenario: "创建新场景",
|
||||||
|
select_scenario: "选择已有场景",
|
||||||
|
scenario_request: "场景/请求",
|
||||||
|
enable_disable: "启用/禁用",
|
||||||
|
test_name: "测试名称",
|
||||||
|
reference: "引用",
|
||||||
|
clone: "复制",
|
||||||
|
cant_reference: '历史测试文件,重新保存后才可被引用'
|
||||||
},
|
},
|
||||||
request: {
|
request: {
|
||||||
debug: "调试",
|
debug: "调试",
|
||||||
|
@ -485,7 +493,7 @@ export default {
|
||||||
xpath_expression: "XPath表达式",
|
xpath_expression: "XPath表达式",
|
||||||
},
|
},
|
||||||
processor: {
|
processor: {
|
||||||
pre_exec_script : "预执行脚本",
|
pre_exec_script: "预执行脚本",
|
||||||
post_exec_script: "后执行脚本",
|
post_exec_script: "后执行脚本",
|
||||||
code_template: "代码模版",
|
code_template: "代码模版",
|
||||||
bean_shell_processor_tip: "仅支持 BeanShell 脚本",
|
bean_shell_processor_tip: "仅支持 BeanShell 脚本",
|
||||||
|
@ -505,7 +513,7 @@ export default {
|
||||||
get_provider_success: "获取成功",
|
get_provider_success: "获取成功",
|
||||||
check_registry_center: "获取失败,请检查Registry Center",
|
check_registry_center: "获取失败,请检查Registry Center",
|
||||||
form_description: "如果当前配置项无值,则取场景配置项的值",
|
form_description: "如果当前配置项无值,则取场景配置项的值",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
api_import: {
|
api_import: {
|
||||||
label: "导入",
|
label: "导入",
|
||||||
|
@ -718,7 +726,7 @@ export default {
|
||||||
test_result: "测试结果",
|
test_result: "测试结果",
|
||||||
result_distribution: "测试结果分布",
|
result_distribution: "测试结果分布",
|
||||||
custom_component: "自定义模块",
|
custom_component: "自定义模块",
|
||||||
defect_list:"缺陷列表",
|
defect_list: "缺陷列表",
|
||||||
create_report: "创建测试报告",
|
create_report: "创建测试报告",
|
||||||
view_report: "查看测试报告",
|
view_report: "查看测试报告",
|
||||||
component_library: "组件库",
|
component_library: "组件库",
|
||||||
|
|
|
@ -413,7 +413,15 @@ export default {
|
||||||
copy: "複製場景",
|
copy: "複製場景",
|
||||||
delete: "删除場景",
|
delete: "删除場景",
|
||||||
disable: "禁用",
|
disable: "禁用",
|
||||||
enable: "啟用"
|
enable: "啟用",
|
||||||
|
create_scenario: "創建新場景",
|
||||||
|
select_scenario: "選擇已有場景",
|
||||||
|
scenario_request: "場景/請求",
|
||||||
|
enable_disable: "啟用/禁用",
|
||||||
|
test_name: "測試名稱",
|
||||||
|
reference: "引用",
|
||||||
|
clone: "複製",
|
||||||
|
cant_reference: '歷史測試文件,重新保存後才可被引用'
|
||||||
},
|
},
|
||||||
request: {
|
request: {
|
||||||
debug: "調試",
|
debug: "調試",
|
||||||
|
|
Loading…
Reference in New Issue