Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
df8984d7ca
|
@ -61,6 +61,11 @@ public class APITestController {
|
|||
apiTestService.update(request, files);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/copy")
|
||||
public void copy(@RequestBody SaveAPITestRequest request) {
|
||||
apiTestService.copy(request);
|
||||
}
|
||||
|
||||
@GetMapping("/get/{testId}")
|
||||
public ApiTestWithBLOBs get(@PathVariable String testId) {
|
||||
return apiTestService.get(testId);
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -69,6 +70,26 @@ public class APITestService {
|
|||
saveFile(test.getId(), files);
|
||||
}
|
||||
|
||||
public void copy(SaveAPITestRequest request) {
|
||||
// copy test
|
||||
ApiTestWithBLOBs copy = get(request.getId());
|
||||
copy.setId(UUID.randomUUID().toString());
|
||||
copy.setName(copy.getName() + " Copy");
|
||||
copy.setCreateTime(System.currentTimeMillis());
|
||||
copy.setUpdateTime(System.currentTimeMillis());
|
||||
copy.setStatus(APITestStatus.Saved.name());
|
||||
copy.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||
apiTestMapper.insert(copy);
|
||||
// copy test file
|
||||
ApiTestFile apiTestFile = getFileByTestId(request.getId());
|
||||
if (apiTestFile != null) {
|
||||
FileMetadata fileMetadata = fileService.copyFile(apiTestFile.getFileId());
|
||||
apiTestFile.setTestId(copy.getId());
|
||||
apiTestFile.setFileId(fileMetadata.getId());
|
||||
apiTestFileMapper.insert(apiTestFile);
|
||||
}
|
||||
}
|
||||
|
||||
public ApiTestWithBLOBs get(String id) {
|
||||
return apiTestMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
<resultMap id="BaseResultMap" type="io.metersphere.dto.LoadTestDTO"
|
||||
extends="io.metersphere.base.mapper.LoadTestMapper.BaseResultMap">
|
||||
<result column="project_name" property="projectName"/>
|
||||
<result column="user_name" property="userName"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="list" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testplan.QueryTestPlanRequest">
|
||||
select load_test.*, project.name as project_name
|
||||
select load_test.*, project.name as project_name, user.name as user_name
|
||||
from load_test
|
||||
left join project on load_test.project_id = project.id
|
||||
left join user on load_test.user_id = user.id
|
||||
<where>
|
||||
<if test="request.name != null">
|
||||
and load_test.name like CONCAT('%', #{request.name},'%')
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
</sql>
|
||||
|
||||
<select id="getReportList" resultType="io.metersphere.dto.ReportDTO">
|
||||
select ltr.id, ltr.name, ltr.test_id as testId, ltr.description,
|
||||
select ltr.id, ltr.name, ltr.test_id as testId, ltr.description, user.name as userName,
|
||||
ltr.create_time as createTime, ltr.update_time as updateTime, ltr.status as status, lt.name as testName
|
||||
from load_test_report ltr join load_test lt on ltr.test_id = lt.id
|
||||
from load_test_report ltr
|
||||
join load_test lt on ltr.test_id = lt.id
|
||||
join user on ltr.user_id = user.id
|
||||
<if test="reportRequest.workspaceId != null">
|
||||
JOIN project on project.id = lt.project_id
|
||||
</if>
|
||||
|
|
|
@ -8,4 +8,5 @@ import lombok.Setter;
|
|||
@Setter
|
||||
public class LoadTestDTO extends LoadTest {
|
||||
private String projectName;
|
||||
private String userName;
|
||||
}
|
||||
|
|
|
@ -18,4 +18,5 @@ public class ReportDTO {
|
|||
private String testName;
|
||||
private String projectId;
|
||||
private String projectName;
|
||||
private String userName;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,9 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
stringBuilder.append(Translator.get("user_not_exists") + ":" + data.getMaintainer() + "; ");
|
||||
}
|
||||
if (testCaseNames.contains(data.getName())) {
|
||||
stringBuilder.append(Translator.get("test_case_already_exists") + ":" + data.getName() + "; ");
|
||||
stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + data.getName() + "; ");
|
||||
} else {
|
||||
testCaseNames.add(data.getName());
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
|
|
@ -3,22 +3,20 @@ package io.metersphere.service;
|
|||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.FileContentMapper;
|
||||
import io.metersphere.base.mapper.FileMetadataMapper;
|
||||
import io.metersphere.base.mapper.ApiTestFileMapper;
|
||||
import io.metersphere.base.mapper.LoadTestFileMapper;
|
||||
import io.metersphere.commons.constants.FileType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class FileService {
|
||||
@Resource
|
||||
|
@ -26,8 +24,6 @@ public class FileService {
|
|||
@Resource
|
||||
private LoadTestFileMapper loadTestFileMapper;
|
||||
@Resource
|
||||
private ApiTestFileMapper ApiTestFileMapper;
|
||||
@Resource
|
||||
private FileContentMapper fileContentMapper;
|
||||
|
||||
public byte[] loadFileAsBytes(String id) {
|
||||
|
@ -50,17 +46,6 @@ public class FileService {
|
|||
return fileMetadataMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public FileMetadata getApiFileMetadataByTestId(String testId) {
|
||||
ApiTestFileExample ApiTestFileExample = new ApiTestFileExample();
|
||||
ApiTestFileExample.createCriteria().andTestIdEqualTo(testId);
|
||||
final List<ApiTestFile> loadTestFiles = ApiTestFileMapper.selectByExample(ApiTestFileExample);
|
||||
|
||||
if (CollectionUtils.isEmpty(loadTestFiles)) {
|
||||
return null;
|
||||
}
|
||||
return fileMetadataMapper.selectByPrimaryKey(loadTestFiles.get(0).getFileId());
|
||||
}
|
||||
|
||||
public FileContent getFileContent(String fileId) {
|
||||
return fileContentMapper.selectByPrimaryKey(fileId);
|
||||
}
|
||||
|
@ -101,6 +86,21 @@ public class FileService {
|
|||
return fileMetadata;
|
||||
}
|
||||
|
||||
public FileMetadata copyFile(String fileId) {
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
FileContent fileContent = getFileContent(fileId);
|
||||
if (fileMetadata != null && fileContent != null) {
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
fileMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
fileContent.setFileId(fileMetadata.getId());
|
||||
fileContentMapper.insert(fileContent);
|
||||
}
|
||||
return fileMetadata;
|
||||
}
|
||||
|
||||
private FileType getFileType(String filename) {
|
||||
int s = filename.lastIndexOf(".") + 1;
|
||||
String type = filename.substring(s);
|
||||
|
|
|
@ -130,13 +130,15 @@ public class ProjectService {
|
|||
}
|
||||
|
||||
private void checkProjectExist (Project project) {
|
||||
ProjectExample example = new ProjectExample();
|
||||
example.createCriteria()
|
||||
.andNameEqualTo(project.getName())
|
||||
.andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
|
||||
.andIdNotEqualTo(project.getId());
|
||||
if (projectMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("project_name_already_exists"));
|
||||
if (project.getName() != null) {
|
||||
ProjectExample example = new ProjectExample();
|
||||
example.createCriteria()
|
||||
.andNameEqualTo(project.getName())
|
||||
.andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
|
||||
.andIdNotEqualTo(project.getId());
|
||||
if (projectMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("project_name_already_exists"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,13 +97,15 @@ public class TestCaseService {
|
|||
}
|
||||
|
||||
private void checkTestCaseExist (TestCaseWithBLOBs testCase) {
|
||||
TestCaseExample example = new TestCaseExample();
|
||||
example.createCriteria()
|
||||
.andNameEqualTo(testCase.getName())
|
||||
.andProjectIdEqualTo(testCase.getProjectId())
|
||||
.andIdNotEqualTo(testCase.getId());
|
||||
if (testCaseMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("test_case_already_exists"));
|
||||
if (testCase.getName() != null) {
|
||||
TestCaseExample example = new TestCaseExample();
|
||||
example.createCriteria()
|
||||
.andNameEqualTo(testCase.getName())
|
||||
.andProjectIdEqualTo(testCase.getProjectId())
|
||||
.andIdNotEqualTo(testCase.getId());
|
||||
if (testCaseMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("test_case_already_exists"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,13 +95,15 @@ public class TestPlanService {
|
|||
}
|
||||
|
||||
private void checkTestPlanExist (TestPlan testPlan) {
|
||||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria()
|
||||
.andNameEqualTo(testPlan.getName())
|
||||
.andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
|
||||
.andIdNotEqualTo(testPlan.getId());
|
||||
if (testPlanMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("plan_name_already_exists"));
|
||||
if (testPlan.getName() != null) {
|
||||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria()
|
||||
.andNameEqualTo(testPlan.getName())
|
||||
.andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
|
||||
.andIdNotEqualTo(testPlan.getId());
|
||||
if (testPlanMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("plan_name_already_exists"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,3 +94,4 @@ options=options
|
|||
please_input_workspace_member=Please input workspace merber
|
||||
test_case_report_template_repeat=The workspace has the same name template
|
||||
plan_name_already_exists=Test plan name already exists
|
||||
test_case_already_exists_excel=There are duplicate test cases in the import file
|
|
@ -94,3 +94,4 @@ options=选项
|
|||
please_input_workspace_member=请填写该工作空间相关人员
|
||||
test_case_report_template_repeat=同一工作空间下不能存在同名模版
|
||||
plan_name_already_exists=测试计划名称已存在
|
||||
test_case_already_exists_excel=导入文件中存在重复用例
|
||||
|
|
|
@ -93,4 +93,5 @@ module_created_automatically=若無該模塊將自動創建
|
|||
options=選項
|
||||
please_input_workspace_member=請填寫該工作空間相關人員
|
||||
test_case_report_template_repeat=同壹工作空間下不能存在同名模版
|
||||
plan_name_already_exists=測試計劃名稱已存在
|
||||
plan_name_already_exists=測試計劃名稱已存在
|
||||
test_case_already_exists_excel=導入文件中存在重復用例
|
|
@ -1,32 +1,28 @@
|
|||
<template>
|
||||
<div class="relate_report">
|
||||
<el-button type="success" plain @click="search">{{$t('api_report.title')}}</el-button>
|
||||
|
||||
<el-dialog :title="$t('api_report.title')" :visible.sync="reportVisible">
|
||||
<el-table :data="tableData" v-loading="result.loading">
|
||||
<el-table-column :label="$t('commons.name')" width="150" show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<el-link type="info" @click="link(scope.row)">{{ scope.row.name }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="250" :label="$t('commons.create_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="250" :label="$t('commons.update_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" :label="$t('commons.status')">
|
||||
<template v-slot:default="{row}">
|
||||
<ms-api-report-status :row="row"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<el-dialog :title="$t('api_report.title')" :visible.sync="reportVisible">
|
||||
<el-table :data="tableData" v-loading="result.loading">
|
||||
<el-table-column :label="$t('commons.name')" width="150" show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<el-link type="info" @click="link(scope.row)">{{ scope.row.name }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="250" :label="$t('commons.create_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="250" :label="$t('commons.update_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" :label="$t('commons.status')">
|
||||
<template v-slot:default="{row}">
|
||||
<ms-api-report-status :row="row"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -49,7 +45,7 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
search() {
|
||||
open() {
|
||||
this.reportVisible = true;
|
||||
|
||||
let url = "/api/report/list/" + this.testId;
|
||||
|
@ -69,7 +65,4 @@
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.relate_report {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -27,7 +27,19 @@
|
|||
|
||||
<el-button type="warning" plain @click="cancel">{{$t('commons.cancel')}}</el-button>
|
||||
|
||||
<ms-api-report-dialog :test-id="id" v-if="test.status === 'Completed'"/>
|
||||
<el-dropdown trigger="click" @command="handleCommand">
|
||||
<el-button class="el-dropdown-link more" icon="el-icon-more" plain/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="report" :disabled="test.status !== 'Completed'">
|
||||
{{$t('api_report.title')}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="performance" :disabled="create">
|
||||
{{$t('api_test.create_performance_test')}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<ms-api-report-dialog :test-id="id" ref="reportDialog"/>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<ms-api-scenario-config :scenarios="test.scenarioDefinition" ref="config"/>
|
||||
|
@ -72,7 +84,7 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
init: function () {
|
||||
init() {
|
||||
this.result = this.$get("/project/listAll", response => {
|
||||
this.projects = response.data;
|
||||
})
|
||||
|
@ -87,7 +99,7 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
getTest: function (id) {
|
||||
getTest(id) {
|
||||
this.result = this.$get("/api/get/" + id, response => {
|
||||
if (response.data) {
|
||||
let item = response.data;
|
||||
|
@ -103,7 +115,7 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
save: function (callback) {
|
||||
save(callback) {
|
||||
this.change = false;
|
||||
let url = this.create ? "/api/create" : "/api/update";
|
||||
this.result = this.$request(this.getOptions(url), () => {
|
||||
|
@ -111,7 +123,7 @@
|
|||
if (callback) callback();
|
||||
});
|
||||
},
|
||||
saveTest: function () {
|
||||
saveTest() {
|
||||
this.save(() => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.create) {
|
||||
|
@ -121,7 +133,7 @@
|
|||
}
|
||||
})
|
||||
},
|
||||
runTest: function () {
|
||||
runTest() {
|
||||
this.result = this.$post("/api/run", {id: this.test.id}, (response) => {
|
||||
this.$success(this.$t('api_test.running'));
|
||||
this.$router.push({
|
||||
|
@ -129,7 +141,7 @@
|
|||
})
|
||||
});
|
||||
},
|
||||
saveRunTest: function () {
|
||||
saveRunTest() {
|
||||
this.change = false;
|
||||
|
||||
this.save(() => {
|
||||
|
@ -137,11 +149,11 @@
|
|||
this.runTest();
|
||||
})
|
||||
},
|
||||
cancel: function () {
|
||||
cancel() {
|
||||
// console.log(this.test.toJMX().xml)
|
||||
this.$router.push('/api/test/list/all');
|
||||
},
|
||||
getOptions: function (url) {
|
||||
getOptions(url) {
|
||||
let formData = new FormData();
|
||||
let request = {
|
||||
id: this.test.id,
|
||||
|
@ -166,15 +178,32 @@
|
|||
'Content-Type': undefined
|
||||
}
|
||||
};
|
||||
},
|
||||
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;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isShowRun() {
|
||||
return this.test.projectId && this.test.name && !this.change;
|
||||
return this.test.isValid() && !this.change;
|
||||
},
|
||||
isDisabled() {
|
||||
return !(this.test.projectId && this.test.name && this.change)
|
||||
return !(this.test.isValid() && this.change)
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -199,4 +228,8 @@
|
|||
.test-project {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.test-container .more {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,16 +3,17 @@
|
|||
<ms-main-container>
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search" :title="$t('commons.test')"
|
||||
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search"
|
||||
:title="$t('commons.test')"
|
||||
@create="create" :createTip="$t('load_test.create')"/>
|
||||
</template>
|
||||
<el-table :data="tableData" class="table-content">
|
||||
<el-table-column :label="$t('commons.name')" width="150" show-overflow-tooltip>
|
||||
<el-table-column :label="$t('commons.name')" width="250" show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<el-link type="info" @click="handleEdit(scope.row)">{{ scope.row.name }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectName" :label="$t('load_test.project_name')" width="150" show-overflow-tooltip/>
|
||||
<el-table-column prop="projectName" :label="$t('load_test.project_name')" width="200" show-overflow-tooltip/>
|
||||
<el-table-column prop="userName" :label="$t('api_test.creator')" width="150" show-overflow-tooltip/>
|
||||
<el-table-column width="250" :label="$t('commons.create_time')">
|
||||
<template v-slot:default="scope">
|
||||
|
@ -31,7 +32,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column width="150" :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator :is-tester-permission="true" @editClick="handleEdit(scope.row)" @deleteClick="handleDelete(scope.row)"/>
|
||||
<ms-table-operators :buttons="buttons" :row="scope.row"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -49,9 +50,13 @@
|
|||
import MsContainer from "../../common/components/MsContainer";
|
||||
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||
import MsApiTestStatus from "./ApiTestStatus";
|
||||
import MsTableOperators from "../../common/components/MsTableOperators";
|
||||
|
||||
export default {
|
||||
components: {MsApiTestStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination, MsTableOperator},
|
||||
components: {
|
||||
MsTableOperators,
|
||||
MsApiTestStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination, MsTableOperator
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
|
@ -62,7 +67,19 @@
|
|||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
loading: false
|
||||
loading: false,
|
||||
buttons: [
|
||||
{
|
||||
tip: this.$t('commons.edit'), icon: "el-icon-edit",
|
||||
exec: this.handleEdit
|
||||
}, {
|
||||
tip: this.$t('commons.copy'), icon: "el-icon-copy-document", type: "success",
|
||||
exec: this.handleCopy
|
||||
}, {
|
||||
tip: this.$t('commons.delete'), icon: "el-icon-delete", type: "danger",
|
||||
exec: this.handleDelete
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -111,6 +128,12 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
handleCopy(test) {
|
||||
this.result = this.$post("/api/copy", {id: test.id}, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.search();
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.projectId = this.$route.params.projectId;
|
||||
this.search();
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<el-input v-model="item.name" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.key')"/>
|
||||
:placeholder="$t('api_test.key')" show-word-limit/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input v-model="item.value" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.value')"/>
|
||||
:placeholder="$t('api_test.value')" show-word-limit/>
|
||||
</el-col>
|
||||
<el-col class="kv-delete">
|
||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-form :model="request" :rules="rules" ref="request" label-width="100px">
|
||||
<el-form-item :label="$t('api_test.request.name')" prop="name">
|
||||
<el-input v-model="request.name" maxlength="100" @input="valid"/>
|
||||
<el-input v-model="request.name" maxlength="100" show-word-limit/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.request.url')" prop="url">
|
||||
|
@ -56,6 +56,13 @@
|
|||
},
|
||||
|
||||
data() {
|
||||
let validateURL = (rule, value, callback) => {
|
||||
try {
|
||||
new URL(this.addProtocol(this.request.url));
|
||||
} catch (e) {
|
||||
callback(this.$t('api_test.request.url_invalid'));
|
||||
}
|
||||
};
|
||||
return {
|
||||
activeName: "parameters",
|
||||
rules: {
|
||||
|
@ -63,7 +70,8 @@
|
|||
{max: 100, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'}
|
||||
],
|
||||
url: [
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'}
|
||||
{max: 100, required: true, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'},
|
||||
{validator: validateURL, trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -74,16 +82,21 @@
|
|||
if (!this.request.url) return;
|
||||
|
||||
let parameters = [];
|
||||
let url = new URL(this.addProtocol(this.request.url));
|
||||
url.searchParams.forEach((value, key) => {
|
||||
if (key && value) {
|
||||
parameters.push(new KeyValue(key, value));
|
||||
}
|
||||
});
|
||||
// 添加一个空的,用于填写
|
||||
parameters.push(new KeyValue());
|
||||
this.request.parameters = parameters;
|
||||
this.request.url = url.toString();
|
||||
try {
|
||||
let url = new URL(this.addProtocol(this.request.url));
|
||||
url.searchParams.forEach((value, key) => {
|
||||
if (key && value) {
|
||||
parameters.push(new KeyValue(key, value));
|
||||
}
|
||||
});
|
||||
// 添加一个空的,用于填写
|
||||
parameters.push(new KeyValue());
|
||||
this.request.parameters = parameters;
|
||||
this.request.url = url.toString();
|
||||
} catch (e) {
|
||||
this.$error(this.$t('api_test.request.url_invalid'), 2000)
|
||||
}
|
||||
|
||||
},
|
||||
methodChange(value) {
|
||||
if (value === 'GET' && this.activeName === 'body') {
|
||||
|
@ -108,10 +121,6 @@
|
|||
}
|
||||
}
|
||||
return url;
|
||||
},
|
||||
valid(value) {
|
||||
value = value.replace(/[`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]·!¥…()—\-《》?:“”【】、;‘’,。]/g, '').replace(/\s/g, "");
|
||||
this.request.name = value;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-form :model="scenario" :rules="rules" ref="scenario" label-width="100px">
|
||||
<el-form-item :label="$t('api_test.scenario.name')" prop="name">
|
||||
<el-input v-model="scenario.name" maxlength="100" @input="valid"/>
|
||||
<el-input v-model="scenario.name" maxlength="100" show-word-limit/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-form-item :label="$t('api_test.scenario.base_url')" prop="url">-->
|
||||
|
@ -43,13 +43,6 @@
|
|||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
valid(value) {
|
||||
value = value.replace(/[`~!@#$%^&*()\-+=<>?:"{}|,./;'\\[\]·!¥…()—\-《》?:“”【】、;‘’,。]/g, '').replace(/\s/g, "");
|
||||
this.scenario.name = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<ms-api-variable-input v-model="item.name" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.variable_name')"/>
|
||||
:placeholder="$t('api_test.variable_name')" show-word-limit/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input v-model="item.value" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.value')"/>
|
||||
:placeholder="$t('api_test.value')" show-word-limit/>
|
||||
</el-col>
|
||||
<el-col class="kv-delete">
|
||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
line-height: 32px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 25px;
|
||||
right: 70px;
|
||||
margin-right: -20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<el-input v-model="time" step="100" size="small" type="number"
|
||||
<el-input :value="value" v-bind="$attrs" step="100" size="small" type="number" @change="change" @input="input"
|
||||
:placeholder="$t('api_test.request.assertions.response_in_time')"/>
|
||||
</el-col>
|
||||
<el-col class="assertion-btn">
|
||||
|
@ -14,32 +14,32 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {ResponseTime} from "../../model/ScenarioModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiAssertionResponseTime",
|
||||
|
||||
props: {
|
||||
edit: Boolean,
|
||||
duration: ResponseTime,
|
||||
value: [Number, String],
|
||||
edit: Boolean,
|
||||
callback: Function
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
time: this.duration.value
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add: function () {
|
||||
setTimeout(() => {
|
||||
this.duration.value = this.time;
|
||||
this.callback();
|
||||
})
|
||||
add() {
|
||||
this.duration.value = this.value;
|
||||
this.callback();
|
||||
},
|
||||
remove: function () {
|
||||
remove() {
|
||||
this.duration.value = undefined;
|
||||
},
|
||||
change(value) {
|
||||
this.$emit('change', value);
|
||||
},
|
||||
input(value) {
|
||||
this.$emit('input', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
<el-col :span="20">
|
||||
<ms-api-assertion-text :list="assertions.regex" v-if="type === options.TEXT" :callback="after"/>
|
||||
<ms-api-assertion-regex :list="assertions.regex" v-if="type === options.REGEX" :callback="after"/>
|
||||
<ms-api-assertion-response-time :duration="assertions.duration" v-if="type === options.RESPONSE_TIME"
|
||||
:callback="after"/>
|
||||
<ms-api-assertion-response-time v-model="time" :duration="assertions.duration"
|
||||
v-if="type === options.RESPONSE_TIME" :callback="after"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
|||
import MsApiAssertionText from "./ApiAssertionText";
|
||||
import MsApiAssertionRegex from "./ApiAssertionRegex";
|
||||
import MsApiAssertionResponseTime from "./ApiAssertionResponseTime";
|
||||
import {ASSERTION_TYPE, Assertions} from "../../model/ScenarioModel";
|
||||
import {ASSERTION_TYPE, Assertions, ResponseTime} from "../../model/ScenarioModel";
|
||||
import MsApiAssertionsEdit from "./ApiAssertionsEdit";
|
||||
|
||||
export default {
|
||||
|
@ -40,6 +40,7 @@
|
|||
data() {
|
||||
return {
|
||||
options: ASSERTION_TYPE,
|
||||
time: "",
|
||||
type: "",
|
||||
}
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<div>
|
||||
{{$t("api_test.request.assertions.response_time")}}
|
||||
</div>
|
||||
<ms-api-assertion-response-time :duration="assertions.duration" :edit="true"/>
|
||||
<ms-api-assertion-response-time v-model="assertions.duration.value" :duration="assertions.duration" :edit="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -110,6 +110,15 @@ export class Test extends BaseConfig {
|
|||
return options;
|
||||
}
|
||||
|
||||
isValid() {
|
||||
for (let i = 0; i < this.scenarioDefinition.length; i++) {
|
||||
if (this.scenarioDefinition[i].isValid()) {
|
||||
return this.projectId && this.name;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
toJMX() {
|
||||
return {
|
||||
name: this.name + '.jmx',
|
||||
|
@ -136,6 +145,19 @@ export class Scenario extends BaseConfig {
|
|||
options.requests = options.requests || [new Request()];
|
||||
return options;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new Scenario(this);
|
||||
}
|
||||
|
||||
isValid() {
|
||||
for (let i = 0; i < this.requests.length; i++) {
|
||||
if (this.requests[i].isValid()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class Request extends BaseConfig {
|
||||
|
@ -394,7 +416,10 @@ class JMXGenerator {
|
|||
}
|
||||
|
||||
addScenarios(testPlan, scenarios) {
|
||||
scenarios.forEach(scenario => {
|
||||
scenarios.forEach(s => {
|
||||
let scenario = s.clone();
|
||||
scenario.name = this.replace(scenario.name);
|
||||
|
||||
let threadGroup = new ThreadGroup(scenario.name || "");
|
||||
|
||||
this.addScenarioVariables(threadGroup, scenario);
|
||||
|
@ -404,6 +429,8 @@ class JMXGenerator {
|
|||
scenario.requests.forEach(request => {
|
||||
if (!request.isValid()) return;
|
||||
|
||||
request.name = this.replace(request.name);
|
||||
|
||||
let httpSamplerProxy = new HTTPSamplerProxy(request.name || "", new JMXRequest(request));
|
||||
|
||||
this.addRequestHeader(httpSamplerProxy, request);
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<span>
|
||||
<ms-table-operator-button v-for="(btn, index) in buttons" :key="index" :isTesterPermission="isTesterPermission(btn)"
|
||||
:tip="btn.tip" :icon="btn.icon" :type="btn.type"
|
||||
@exec="click(btn)" @click.stop="clickStop(btn)"/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsTableOperatorButton from "./MsTableOperatorButton";
|
||||
|
||||
export default {
|
||||
name: "MsTableOperators",
|
||||
components: {MsTableOperatorButton},
|
||||
props: {
|
||||
row: Object,
|
||||
buttons: Array
|
||||
},
|
||||
methods: {
|
||||
click(btn) {
|
||||
if (btn.exec instanceof Function) {
|
||||
btn.exec(this.row);
|
||||
}
|
||||
},
|
||||
clickStop(btn) {
|
||||
if (btn.stop instanceof Function) {
|
||||
btn.stop(this.row);
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isTesterPermission() {
|
||||
return function (btn) {
|
||||
return btn.isTesterPermission !== false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -44,6 +44,7 @@
|
|||
},
|
||||
methods: {
|
||||
checkLanguage(lang) {
|
||||
if (!lang) return;
|
||||
this.$setLang(lang);
|
||||
switch (lang) {
|
||||
case ZH_CN:
|
||||
|
|
|
@ -204,6 +204,11 @@ const router = new VueRouter({
|
|||
name: 'trackHome',
|
||||
component: TrackHome,
|
||||
},
|
||||
{
|
||||
path: 'case/create/',
|
||||
name: 'testCaseCreate',
|
||||
component: TestCase,
|
||||
},
|
||||
{
|
||||
path: 'case/:projectId',
|
||||
name: 'testCase',
|
||||
|
|
|
@ -131,13 +131,13 @@
|
|||
this.$warning(this.$t('report.generation_error'));
|
||||
break;
|
||||
case 'Starting':
|
||||
this.$warning("测试处于开始状态,请稍后查看报告!");
|
||||
this.$warning(this.$t('report.start_status'));
|
||||
break;
|
||||
case 'Reporting':
|
||||
this.$info(this.$t('report.being_generated'));
|
||||
break;
|
||||
case 'Running':
|
||||
this.$warning("测试处于运行状态,请稍后查看报告!");
|
||||
this.$warning(this.$t('report.run_status'));
|
||||
break;
|
||||
case 'Completed':
|
||||
default:
|
||||
|
@ -178,6 +178,7 @@
|
|||
this.status = data.status;
|
||||
this.reportName = data.name;
|
||||
this.testName = data.testName;
|
||||
this.testId = data.testId;
|
||||
this.projectName = data.projectName;
|
||||
|
||||
this.$set(this.report, "id", reportId);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('commons.name')"
|
||||
width="200"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
|
@ -28,6 +29,12 @@
|
|||
width="150"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="userName"
|
||||
:label="$t('report.user_name')"
|
||||
width="150"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
width="250"
|
||||
:label="$t('commons.create_time')">
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
this.avgResponseTime = '0';
|
||||
this.responseTime90 = '0';
|
||||
this.avgBandwidth = '0';
|
||||
this.$warning("报告生成错误!")
|
||||
this.$warning(this.$t('report.generation_error'));
|
||||
})
|
||||
this.$get("/performance/report/content/load_chart/" + this.id).then(res => {
|
||||
let data = res.data.data;
|
||||
|
|
|
@ -115,7 +115,23 @@
|
|||
|
||||
this.listProjects();
|
||||
},
|
||||
mounted() {
|
||||
this.importAPITest();
|
||||
},
|
||||
methods: {
|
||||
importAPITest() {
|
||||
let apiTest = this.$store.state.api.test;
|
||||
if (apiTest && apiTest.name) {
|
||||
this.testPlan.projectId = apiTest.projectId;
|
||||
this.testPlan.name = apiTest.name;
|
||||
let blob = new Blob([apiTest.jmx.xml], {type: "application/octet-stream"});
|
||||
let file = new File([blob], apiTest.jmx.name);
|
||||
this.$refs.basicConfig.beforeUpload(file);
|
||||
this.$refs.basicConfig.handleUpload({file: file});
|
||||
this.active = '1';
|
||||
this.$store.commit("clearTest");
|
||||
}
|
||||
},
|
||||
listProjects() {
|
||||
this.result = this.$get(this.listProjectPath, response => {
|
||||
this.projects = response.data;
|
||||
|
|
|
@ -28,6 +28,12 @@
|
|||
width="150"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="userName"
|
||||
:label="$t('load_test.user_name')"
|
||||
width="150"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
width="250"
|
||||
:label="$t('commons.create_time')">
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
accept=".jmx,.csv"
|
||||
drag
|
||||
action=""
|
||||
:limit="5"
|
||||
:limit="2"
|
||||
multiple
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUpload"
|
||||
|
@ -175,7 +175,7 @@
|
|||
}
|
||||
},
|
||||
handleExceed() {
|
||||
this.$error(this.$t('load_test.delete_file'));
|
||||
this.$error(this.$t('load_test.file_size_limit'));
|
||||
},
|
||||
fileValidator(file) {
|
||||
/// todo: 是否需要对文件内容和大小做限制
|
||||
|
|
|
@ -88,25 +88,23 @@
|
|||
mounted() {
|
||||
this.getProjects();
|
||||
this.refresh();
|
||||
if (this.$route.params.projectId){
|
||||
this.getProjectById(this.$route.params.projectId)
|
||||
}
|
||||
if (this.$route.path.indexOf("/track/case/edit") >= 0){
|
||||
if (this.$route.path.indexOf("/track/case/edit") >= 0 || this.$route.path.indexOf("/track/case/create") >= 0){
|
||||
this.openRecentTestCaseEditDialog();
|
||||
this.$router.push('/track/case/all');
|
||||
} else if (this.$route.params.projectId){
|
||||
this.getProjectById(this.$route.params.projectId)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route'(to, from) {
|
||||
let path = to.path;
|
||||
if (to.params.projectId){
|
||||
this.getProjectById(to.params.projectId)
|
||||
this.getProjects();
|
||||
}
|
||||
if (path.indexOf("/track/case/edit") >= 0){
|
||||
if (path.indexOf("/track/case/edit") >= 0 || path.indexOf("/track/case/create") >= 0){
|
||||
this.openRecentTestCaseEditDialog();
|
||||
this.$router.push('/track/case/all');
|
||||
this.getProjects();
|
||||
} else if (to.params.projectId){
|
||||
this.getProjectById(to.params.projectId);
|
||||
this.getProjects();
|
||||
}
|
||||
},
|
||||
currentProject() {
|
||||
|
@ -160,6 +158,10 @@
|
|||
},
|
||||
editTestCase(testCase) {
|
||||
this.testCaseReadOnly = false;
|
||||
if (this.treeNodes.length < 1) {
|
||||
this.$warning(this.$t('test_track.case.create_module_first'));
|
||||
return;
|
||||
}
|
||||
this.$refs.testCaseEditDialog.open(testCase);
|
||||
},
|
||||
copyTestCase(testCase) {
|
||||
|
@ -187,13 +189,22 @@
|
|||
},
|
||||
openRecentTestCaseEditDialog() {
|
||||
let caseId = this.$route.params.caseId;
|
||||
this.getProjectByCaseId(caseId);
|
||||
this.$get('/test/case/get/' + caseId, response => {
|
||||
if (response.data) {
|
||||
this.testCaseReadOnly = false;
|
||||
this.$refs.testCaseEditDialog.open(response.data);
|
||||
if (caseId) {
|
||||
this.getProjectByCaseId(caseId);
|
||||
this.$get('/test/case/get/' + caseId, response => {
|
||||
if (response.data) {
|
||||
this.testCaseReadOnly = false;
|
||||
this.$refs.testCaseEditDialog.open(response.data);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.testCaseReadOnly = false;
|
||||
if (this.treeNodes.length < 1) {
|
||||
this.$warning(this.$t('test_track.case.create_module_first'));
|
||||
return;
|
||||
}
|
||||
});
|
||||
this.$refs.testCaseEditDialog.open();
|
||||
}
|
||||
},
|
||||
getProjectById(id) {
|
||||
if (id && id != 'all') {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<el-divider/>
|
||||
<ms-show-all :index="'/track/case/all'"/>
|
||||
<el-menu-item :index="testCaseEditPath" class="blank_item"></el-menu-item>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/track/case/create'" :title="$t('test_track.case.create_case')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-if="isCurrentWorkspaceUser" index="7" popper-class="submenu">
|
||||
|
|
|
@ -232,11 +232,23 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
handleClose(done) {
|
||||
listenGoBack() {
|
||||
//监听浏览器返回操作,关闭该对话框
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', this.goBack, false);
|
||||
}
|
||||
},
|
||||
goBack() {
|
||||
this.handleClose();
|
||||
},
|
||||
handleClose() {
|
||||
//移除监听,防止监听其他页面
|
||||
window.removeEventListener('popstate', this.goBack, false);
|
||||
this.showDialog = false;
|
||||
},
|
||||
cancel() {
|
||||
this.showDialog = false;
|
||||
this.handleClose();
|
||||
this.$emit('refreshTable');
|
||||
},
|
||||
statusChange(status) {
|
||||
|
@ -296,9 +308,11 @@
|
|||
item.steptResults.push(item.steps[i]);
|
||||
}
|
||||
this.testCase = item;
|
||||
this.initTest();
|
||||
},
|
||||
openTestCaseEdit(testCase) {
|
||||
this.showDialog = true;
|
||||
this.listenGoBack();
|
||||
this.initData(testCase);
|
||||
},
|
||||
initTest() {
|
||||
|
@ -327,7 +341,6 @@
|
|||
this.index = i;
|
||||
this.getTestCase(i);
|
||||
this.getRelatedTest();
|
||||
this.initTest();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -91,6 +91,16 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
listenGoBack() {
|
||||
//监听浏览器返回操作,关闭该对话框
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', this.goBack, false);
|
||||
}
|
||||
},
|
||||
goBack() {
|
||||
this.handleClose();
|
||||
},
|
||||
open(id, isReport) {
|
||||
if (isReport) {
|
||||
this.isReport = isReport;
|
||||
|
@ -112,6 +122,7 @@
|
|||
this.initComponents();
|
||||
}
|
||||
this.showDialog = true;
|
||||
this.listenGoBack();
|
||||
},
|
||||
initComponents() {
|
||||
this.componentMap.forEach((value, key) =>{
|
||||
|
@ -134,6 +145,7 @@
|
|||
});
|
||||
},
|
||||
handleClose() {
|
||||
window.removeEventListener('popstate', this.goBack, false);
|
||||
this.showDialog = false;
|
||||
},
|
||||
change(evt) {
|
||||
|
@ -221,7 +233,7 @@
|
|||
}
|
||||
this.$post(url + this.type, param, () =>{
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.showDialog = false;
|
||||
this.handleClose();
|
||||
this.$emit('refresh');
|
||||
});
|
||||
},
|
||||
|
|
|
@ -78,12 +78,23 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
listenGoBack() {
|
||||
//监听浏览器返回操作,关闭该对话框
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', this.goBack, false);
|
||||
}
|
||||
},
|
||||
goBack() {
|
||||
this.handleClose();
|
||||
},
|
||||
open(id) {
|
||||
if (id) {
|
||||
this.reportId = id;
|
||||
}
|
||||
this.getReport();
|
||||
this.showDialog = true;
|
||||
this.listenGoBack();
|
||||
},
|
||||
getReport() {
|
||||
this.result = this.$get('/case/report/get/' + this.reportId, response => {
|
||||
|
@ -113,6 +124,7 @@
|
|||
});
|
||||
},
|
||||
handleClose() {
|
||||
window.removeEventListener('popstate', this.goBack, false);
|
||||
this.showDialog = false;
|
||||
},
|
||||
handleEdit() {
|
||||
|
|
|
@ -3,7 +3,24 @@ import Vuex from 'vuex'
|
|||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const API = {
|
||||
state: {
|
||||
test: {}
|
||||
},
|
||||
mutations: {
|
||||
setTest(state, test) {
|
||||
state.test = test;
|
||||
},
|
||||
clearTest(state) {
|
||||
state.test = {};
|
||||
}
|
||||
},
|
||||
actions: {},
|
||||
getters: {}
|
||||
}
|
||||
|
||||
export default new Vuex.Store({})
|
||||
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
api: API
|
||||
}
|
||||
})
|
||||
|
|
|
@ -34,12 +34,12 @@ export default {
|
|||
})
|
||||
};
|
||||
|
||||
Vue.prototype.$error = function (message) {
|
||||
Vue.prototype.$error = function (message, duration) {
|
||||
Message.error({
|
||||
message: message,
|
||||
type: "error",
|
||||
showClose: true,
|
||||
duration: 10000
|
||||
duration: duration || 10000
|
||||
})
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ export default {
|
|||
'save_success': 'Saved successfully',
|
||||
'delete_success': 'Deleted successfully',
|
||||
'modify_success': 'Modify Success',
|
||||
'copy_success': 'Copy Success',
|
||||
'delete_cancel': 'Deleted Cancel',
|
||||
'confirm': 'Confirm',
|
||||
'cancel': 'Cancel',
|
||||
|
@ -192,6 +193,9 @@ export default {
|
|||
'generation_error': 'Report generation error, cannot be viewed!',
|
||||
'being_generated': 'Report is being generated...',
|
||||
'delete_confirm': 'Confirm delete: ',
|
||||
'start_status': 'The test is starting, please check the report later!',
|
||||
'run_status': 'The test is running, please check the report later!',
|
||||
'user_name': 'Creator'
|
||||
},
|
||||
load_test: {
|
||||
'operating': 'Operating',
|
||||
|
@ -210,7 +214,7 @@ export default {
|
|||
'is_running': 'Test is running! ',
|
||||
'test_name_is_null': 'Test name cannot be empty! ',
|
||||
'project_is_null': 'Project cannot be empty! ',
|
||||
'jmx_is_null': 'Can only contain one JMX file',
|
||||
'jmx_is_null': 'Must contain a JMX file, and can only contain a JMX file!',
|
||||
'file_name': 'File name',
|
||||
'file_size': 'File size',
|
||||
'file_type': 'File Type',
|
||||
|
@ -220,7 +224,8 @@ export default {
|
|||
'upload_type': 'Only JMX/CSV files can be uploaded',
|
||||
'related_file_not_found': "No related test file found!",
|
||||
'delete_file_confirm': 'Confirm delete file:',
|
||||
'delete_file': "Please delete an existing file first!",
|
||||
'file_size_limit': "The number of files exceeds the limit!",
|
||||
'delete_file': "The file already exists, please delete the file with the same name first!",
|
||||
'thread_num': 'Concurrent users:',
|
||||
'input_thread_num': 'Please enter the number of threads',
|
||||
'duration': 'Duration time (minutes):',
|
||||
|
@ -249,6 +254,7 @@ export default {
|
|||
'select_resource_pool': 'Please Select Resource Pool',
|
||||
'resource_pool_is_null': 'Resource Pool is empty',
|
||||
'download_log_file': 'Download',
|
||||
'user_name': 'Creator'
|
||||
},
|
||||
api_test: {
|
||||
creator: "Creator",
|
||||
|
@ -263,12 +269,14 @@ export default {
|
|||
copied: "copied",
|
||||
key: "Key",
|
||||
value: "Value",
|
||||
create_performance_test: "Create Performance Test",
|
||||
scenario: {
|
||||
config: "Scenario Config",
|
||||
input_name: "Please enter the scenario name",
|
||||
name: "Scenario Name",
|
||||
base_url: "Base URL",
|
||||
base_url_description: "Base URL as URL prefix for all requests",
|
||||
url_invalid: "Invalid URL",
|
||||
variables: "Variables",
|
||||
headers: "Headers",
|
||||
kv_description: "Variables are available for all requests",
|
||||
|
@ -391,6 +399,7 @@ export default {
|
|||
delete: "Delete case",
|
||||
save_create_continue: "Save and create continue",
|
||||
please_create_project: "No project available, please create the project first",
|
||||
create_module_first: "Please create module first",
|
||||
import: {
|
||||
import: "Import test case",
|
||||
case_import: "Import test case",
|
||||
|
|
|
@ -10,6 +10,7 @@ export default {
|
|||
'save': '保存',
|
||||
'save_success': '保存成功',
|
||||
'delete_success': '删除成功',
|
||||
'copy_success': '复制成功',
|
||||
'modify_success': '修改成功',
|
||||
'delete_cancel': '已取消删除',
|
||||
'confirm': '确定',
|
||||
|
@ -190,6 +191,9 @@ export default {
|
|||
'generation_error': '报告生成错误,无法查看!',
|
||||
'being_generated': '报告正在生成中...',
|
||||
'delete_confirm': '确认删除报告: ',
|
||||
'start_status': '测试处于开始状态,请稍后查看报告!',
|
||||
'run_status': '测试处于运行状态,请稍后查看报告!',
|
||||
'user_name': '创建人'
|
||||
},
|
||||
load_test: {
|
||||
'operating': '操作',
|
||||
|
@ -207,7 +211,7 @@ export default {
|
|||
'is_running': '正在运行!',
|
||||
'test_name_is_null': '测试名称不能为空!',
|
||||
'project_is_null': '项目不能为空!',
|
||||
'jmx_is_null': '只能包含一个JMX文件!',
|
||||
'jmx_is_null': '必需包含一个JMX文件,且只能包含一个JMX文件!',
|
||||
'file_name': '文件名',
|
||||
'file_size': '文件大小',
|
||||
'file_type': '文件类型',
|
||||
|
@ -217,7 +221,8 @@ export default {
|
|||
'upload_type': '只能上传JMX/CSV文件',
|
||||
'related_file_not_found': "未找到关联的测试文件!",
|
||||
'delete_file_confirm': '确认删除文件: ',
|
||||
'delete_file': "请先删除已存在的文件!",
|
||||
'file_size_limit': "文件个数超出限制!",
|
||||
'delete_file': "文件已存在,请先删除同名文件!",
|
||||
'thread_num': '并发用户数:',
|
||||
'input_thread_num': '请输入线程数',
|
||||
'duration': '压测时长(分钟):',
|
||||
|
@ -247,6 +252,7 @@ export default {
|
|||
'resource_pool_is_null': '资源池为空',
|
||||
'download_log_file': '下载完整日志文件',
|
||||
'pressure_prediction_chart': '压力预估图',
|
||||
'user_name': '创建人'
|
||||
},
|
||||
api_test: {
|
||||
creator: "创建人",
|
||||
|
@ -260,6 +266,7 @@ export default {
|
|||
copied: "已拷贝",
|
||||
key: "键",
|
||||
value: "值",
|
||||
create_performance_test: "创建性能测试",
|
||||
scenario: {
|
||||
config: "场景配置",
|
||||
input_name: "请输入场景名称",
|
||||
|
@ -280,6 +287,7 @@ export default {
|
|||
method: "请求方法",
|
||||
url: "请求URL",
|
||||
url_description: "例如: https://fit2cloud.com",
|
||||
url_invalid: "URL无效",
|
||||
parameters: "请求参数",
|
||||
parameters_desc: "参数追加到URL,例如https://fit2cloud.com/entries?key1=Value1&Key2=Value2",
|
||||
headers: "请求头",
|
||||
|
@ -388,6 +396,7 @@ export default {
|
|||
delete: "删除用例",
|
||||
save_create_continue: "保存并继续创建",
|
||||
please_create_project: "暂无项目,请先创建项目",
|
||||
create_module_first: "请先新建模块",
|
||||
import: {
|
||||
import: "导入用例",
|
||||
case_import: "导入测试用例",
|
||||
|
|
|
@ -10,6 +10,7 @@ export default {
|
|||
'save': '保存',
|
||||
'save_success': '保存成功',
|
||||
'delete_success': '刪除成功',
|
||||
'copy_success': '複製成功',
|
||||
'modify_success': '修改成功',
|
||||
'delete_cancel': '已取消刪除',
|
||||
'confirm': '確定',
|
||||
|
@ -191,6 +192,9 @@ export default {
|
|||
'generation_error': '報告生成錯誤,無法查看!',
|
||||
'being_generated': '報告正在生成中...',
|
||||
'delete_confirm': '確認刪除報告: ',
|
||||
'start_status': '測試處於開始狀態,請稍後查看報告!',
|
||||
'run_status': '測試處於運行狀態,請稍後查看報告!',
|
||||
'user_name': '創建人'
|
||||
},
|
||||
load_test: {
|
||||
'operating': '操作',
|
||||
|
@ -208,7 +212,7 @@ export default {
|
|||
'is_running': '正在運行! ',
|
||||
'test_name_is_null': '測試名稱不能為空! ',
|
||||
'project_is_null': '項目不能為空! ',
|
||||
'jmx_is_null': '只能包含一個JMX文件! ',
|
||||
'jmx_is_null': '必需包含一個JMX文件,且只能包含一個JMX文件!',
|
||||
'file_name': '文件名',
|
||||
'file_size': '文件大小',
|
||||
'file_type': '文件類型',
|
||||
|
@ -218,7 +222,8 @@ export default {
|
|||
'upload_type': '只能上傳JMX/CSV文件',
|
||||
'related_file_not_found': "未找到關聯的測試文件!",
|
||||
'delete_file_confirm': '確認刪除文件: ',
|
||||
'delete_file': "請先刪除已存在的文件!",
|
||||
'file_size_limit': "文件個數超出限制!",
|
||||
'delete_file': "文件已存在,請先刪除同名文件!",
|
||||
'thread_num': '並髮用戶數:',
|
||||
'input_thread_num': '請輸入線程數',
|
||||
'duration': '壓測時長(分鐘):',
|
||||
|
@ -248,6 +253,7 @@ export default {
|
|||
'resource_pool_is_null': '資源池為空',
|
||||
'download_log_file': '下載完整日誌文件',
|
||||
'pressure_prediction_chart': '壓力預估圖',
|
||||
'user_name': '創建人'
|
||||
},
|
||||
api_test: {
|
||||
title: "測試",
|
||||
|
@ -261,6 +267,7 @@ export default {
|
|||
copied: "已拷貝",
|
||||
key: "鍵",
|
||||
value: "值",
|
||||
create_performance_test: "創建性能測試",
|
||||
scenario: {
|
||||
creator: "創建人",
|
||||
config: "場景配寘",
|
||||
|
@ -282,6 +289,7 @@ export default {
|
|||
method: "請求方法",
|
||||
url: "請求URL",
|
||||
url_description: "例如:https://fit2cloud.com",
|
||||
url_invalid: "URL無效",
|
||||
parameters: "請求參數",
|
||||
parameters_desc: "參數追加到URL,例如https://fit2cloud.com/entries?key1=Value1&Key2=Value2",
|
||||
headers: "請求頭",
|
||||
|
@ -390,6 +398,7 @@ export default {
|
|||
delete: "删除用例",
|
||||
save_create_continue: "保存並繼續創建",
|
||||
please_create_project: "暫無項目,請先創建項目",
|
||||
create_module_first: "請先新建模塊",
|
||||
import: {
|
||||
import: "導入用例",
|
||||
case_import: "導入測試用例",
|
||||
|
|
Loading…
Reference in New Issue