Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
fdfee3a6b8
|
@ -47,10 +47,6 @@ public class APITestController {
|
|||
return apiTestService.getApiTestByProjectId(projectId);
|
||||
}
|
||||
|
||||
@GetMapping("/state/get/{testId}")
|
||||
public ApiTest apiState(@PathVariable String testId) {
|
||||
return apiTestService.getApiTestByTestId(testId);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/schedule/update")
|
||||
public void updateSchedule(@RequestBody Schedule request) {
|
||||
|
|
|
@ -126,9 +126,6 @@ public class APITestService {
|
|||
return null;
|
||||
}
|
||||
|
||||
public ApiTest getApiTestByTestId(String testId) {
|
||||
return apiTestMapper.selectByPrimaryKey(testId);
|
||||
}
|
||||
|
||||
public List<ApiTest> getApiTestByProjectId(String projectId) {
|
||||
return extApiTestMapper.getApiTestByProjectId(projectId);
|
||||
|
|
|
@ -225,7 +225,12 @@
|
|||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
order by update_time desc
|
||||
<if test="request.orders != null and request.orders.size() > 0">
|
||||
order by
|
||||
<foreach collection="request.orders" separator="," item="order">
|
||||
${order.name} ${order.type}
|
||||
</foreach>
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getMaxNumByProjectId" resultType="io.metersphere.base.domain.TestCase">
|
||||
|
|
|
@ -128,7 +128,6 @@ public class UserController {
|
|||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN, RoleConstants.ORG_ADMIN, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public List<User> getUserList() {
|
||||
return userService.getUserList();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.track.request.testcase;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
@ -10,4 +11,5 @@ import java.util.List;
|
|||
@Setter
|
||||
public class TestCaseBatchRequest extends TestCaseWithBLOBs {
|
||||
private List<String> ids;
|
||||
private List<OrderRequest> orders;
|
||||
}
|
||||
|
|
|
@ -356,6 +356,12 @@ public class TestCaseService {
|
|||
}
|
||||
|
||||
private List<TestCaseExcelData> generateTestCaseExcel(TestCaseBatchRequest request) {
|
||||
List<OrderRequest> orderList = ServiceUtils.getDefaultOrder(request.getOrders());
|
||||
OrderRequest order = new OrderRequest();
|
||||
order.setName("sort");
|
||||
order.setType("desc");
|
||||
orderList.add(order);
|
||||
request.setOrders(orderList);
|
||||
List<TestCaseDTO> TestCaseList = extTestCaseMapper.listByTestCaseIds(request);
|
||||
List<TestCaseExcelData> list = new ArrayList<>();
|
||||
StringBuilder step = new StringBuilder("");
|
||||
|
@ -466,6 +472,7 @@ public class TestCaseService {
|
|||
|
||||
/**
|
||||
* 导入用例前,检查数据库是否存在此用例
|
||||
*
|
||||
* @param testCaseWithBLOBs
|
||||
* @return
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE load_test_report_result
|
||||
MODIFY report_value LONGTEXT NULL;
|
|
@ -62,6 +62,7 @@ export default {
|
|||
let url = "/api/report/get/" + this.reportId;
|
||||
this.$get(url, response => {
|
||||
this.report = response.data || {};
|
||||
if (response.data) {
|
||||
if (this.isNotRunning) {
|
||||
try {
|
||||
this.content = JSON.parse(this.report.content);
|
||||
|
@ -74,6 +75,10 @@ export default {
|
|||
} else {
|
||||
setTimeout(this.getReport, 2000)
|
||||
}
|
||||
} else {
|
||||
this.loading = false;
|
||||
this.$error(this.$t('api_report.not_exist'));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
<ms-api-report-dialog :test-id="id" ref="reportDialog"/>
|
||||
|
||||
<ms-schedule-config :schedule="test.schedule" :save="saveCronExpression" @scheduleChange="saveSchedule" :check-open="checkScheduleEdit"/>
|
||||
<ms-schedule-config :schedule="test.schedule" :is-read-only="isReadOnly" :save="saveCronExpression" @scheduleChange="saveSchedule" :check-open="checkScheduleEdit"/>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<ms-api-scenario-config :is-read-only="isReadOnly" :scenarios="test.scenarioDefinition" :project-id="test.projectId" ref="config"/>
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
<el-input v-if="!suggestions" :disabled="isReadOnly" v-model="item.name" size="small" maxlength="200"
|
||||
@change="change"
|
||||
:placeholder="keyText" show-word-limit/>
|
||||
<el-autocomplete :maxlength="200" v-if="suggestions" v-model="item.name" size="small"
|
||||
<el-autocomplete :disabled="isReadOnly" :maxlength="200" v-if="suggestions" v-model="item.name" size="small"
|
||||
:fetch-suggestions="querySearch" @change="change" :placeholder="keyText"
|
||||
show-word-limit/>
|
||||
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input :disabled="isReadOnly" v-model="item.value" size="small" maxlength="2000" @change="change"
|
||||
<el-input :disabled="isReadOnly" v-model="item.value" size="small" @change="change"
|
||||
:placeholder="valueText" show-word-limit/>
|
||||
</el-col>
|
||||
<el-col class="kv-delete">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:placeholder="$t('api_test.request.extract.json_path_expression')"/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input :disabled="isReadOnly" v-model="jsonPath.expect" maxlength="2000" size="small" show-word-limit
|
||||
<el-input :disabled="isReadOnly" v-model="jsonPath.expect" size="small" show-word-limit
|
||||
:placeholder="$t('api_test.request.assertions.expect')"/>
|
||||
</el-col>
|
||||
<el-col class="assertion-btn">
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</el-select>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input :disabled="isReadOnly" v-model="regex.expression" maxlength="2000" size="small" show-word-limit
|
||||
<el-input :disabled="isReadOnly" v-model="regex.expression" size="small" show-word-limit
|
||||
:placeholder="$t('api_test.request.assertions.expression')"/>
|
||||
</el-col>
|
||||
<el-col class="assertion-btn">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
@change="change" show-word-limit :placeholder="$t('api_test.variable_name')"/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input :disabled="isReadOnly" v-model="common.expression" maxlength="2000" size="small" show-word-limit
|
||||
<el-input :disabled="isReadOnly" v-model="common.expression" size="small" show-word-limit
|
||||
:placeholder="expression"/>
|
||||
</el-col>
|
||||
<el-col class="extract-btn">
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<i class="el-icon-date" size="small"></i>
|
||||
<span class="character" @click="scheduleEdit">SCHEDULER</span>
|
||||
</span>
|
||||
<el-switch :disabled="!schedule.value" v-model="schedule.enable" @change="scheduleChange"/>
|
||||
<ms-schedule-edit :schedule="schedule" :save="save" :custom-validate="customValidate" ref="scheduleEdit"/>
|
||||
<el-switch :disabled="!schedule.value && isReadOnly" v-model="schedule.enable" @change="scheduleChange"/>
|
||||
<ms-schedule-edit :is-read-only="isReadOnly" :schedule="schedule" :save="save" :custom-validate="customValidate" ref="scheduleEdit"/>
|
||||
<crontab-result v-show="false" :ex="schedule.value" ref="crontabResult" @resultListChange="resultListChange"/>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -44,6 +44,10 @@
|
|||
type: Function,
|
||||
default: defaultCustomValidate
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
scheduleEdit() {
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
<el-form :model="form" :rules="rules" ref="from">
|
||||
<el-form-item
|
||||
prop="cronValue">
|
||||
<el-input v-model="form.cronValue" class="inp" :placeholder="$t('schedule.please_input_cron_expression')"/>
|
||||
<el-input :disabled="isReadOnly" v-model="form.cronValue" class="inp" :placeholder="$t('schedule.please_input_cron_expression')"/>
|
||||
<!-- <el-button type="primary" @click="showCronDialog">{{$t('schedule.generate_expression')}}</el-button>-->
|
||||
<el-button type="primary" @click="saveCron">{{$t('commons.save')}}</el-button>
|
||||
<el-button :disabled="isReadOnly" type="primary" @click="saveCron">{{$t('commons.save')}}</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-link type="primary" @click="showCronDialog">{{$t('schedule.generate_expression')}}</el-link>
|
||||
<el-link :disabled="isReadOnly" type="primary" @click="showCronDialog">{{$t('schedule.generate_expression')}}</el-link>
|
||||
</el-form-item>
|
||||
<crontab-result :ex="form.cronValue" ref="crontabResult" />
|
||||
</el-form>
|
||||
|
@ -38,6 +38,10 @@
|
|||
type: Function,
|
||||
default: defaultCustomValidate
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'schedule.value'() {
|
||||
|
|
|
@ -43,12 +43,12 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider></el-divider>
|
||||
<el-divider/>
|
||||
|
||||
<el-tabs v-model="active" type="border-card" :stretch="true">
|
||||
<el-tab-pane :label="$t('report.test_overview')">
|
||||
<!-- <ms-report-test-overview :id="reportId" :status="status"/>-->
|
||||
<ms-report-test-overview :report="report"/>
|
||||
<ms-report-test-overview :report="report" ref="testOverview"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('report.test_request_statistics')">
|
||||
<ms-report-request-statistics :report="report"/>
|
||||
|
@ -63,8 +63,8 @@
|
|||
|
||||
</el-card>
|
||||
<el-dialog :title="$t('report.test_stop_now_confirm')" :visible.sync="dialogFormVisible" width="30%">
|
||||
<p v-html="$t('report.force_stop_tips')"></p>
|
||||
<p v-html="$t('report.stop_tips')"></p>
|
||||
<p v-html="$t('report.force_stop_tips')"/>
|
||||
<p v-html="$t('report.stop_tips')"/>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="danger" size="small" @click="stopTest(true)">{{$t('report.force_stop_btn')}}
|
||||
</el-button>
|
||||
|
@ -190,7 +190,7 @@
|
|||
} else {
|
||||
this.report.status = 'Completed';
|
||||
}
|
||||
})
|
||||
});
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
rerun(testId) {
|
||||
|
@ -201,7 +201,7 @@
|
|||
}).then(() => {
|
||||
this.result = this.$post('/performance/run', {id: testId, triggerMode: 'MANUAL'}, (response) => {
|
||||
this.reportId = response.data;
|
||||
this.$router.push({path: '/performance/report/view/' + this.reportId})
|
||||
this.$router.push({path: '/performance/report/view/' + this.reportId});
|
||||
// 注册 socket
|
||||
this.initWebSocket();
|
||||
})
|
||||
|
@ -235,6 +235,7 @@
|
|||
this.reportId = this.$route.path.split('/')[4];
|
||||
this.result = this.$get("/performance/report/" + this.reportId, res => {
|
||||
let data = res.data;
|
||||
if (data) {
|
||||
this.status = data.status;
|
||||
this.$set(this.report, "id", this.reportId);
|
||||
this.$set(this.report, "status", data.status);
|
||||
|
@ -242,9 +243,13 @@
|
|||
if (this.status === "Completed" || this.status === "Running") {
|
||||
this.initReportTimeInfo();
|
||||
}
|
||||
})
|
||||
this.initBreadcrumb();
|
||||
this.initWebSocket();
|
||||
} else {
|
||||
this.$error(this.$t('report.not_exist'))
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.websocket.close() //离开路由之后断开websocket连接
|
||||
|
@ -288,6 +293,8 @@
|
|||
} else {
|
||||
this.clearData();
|
||||
}
|
||||
} else {
|
||||
this.$error(this.$t('report.not_exist'));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@
|
|||
<el-table-column label="Throughput">
|
||||
<el-table-column
|
||||
prop="transactions"
|
||||
label="Transactions"
|
||||
width="100"
|
||||
label="Transactions/s"
|
||||
width="150"
|
||||
/>
|
||||
</el-table-column>
|
||||
|
||||
|
@ -76,13 +76,13 @@
|
|||
prop="received"
|
||||
label="Received"
|
||||
align="center"
|
||||
width="200"
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="sent"
|
||||
label="Sent"
|
||||
align="center"
|
||||
width="200"
|
||||
width="150"
|
||||
/>
|
||||
</el-table-column>
|
||||
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
</template>
|
||||
<el-table border class="adjust-table" @row-click="link" :data="items" style="width: 100%" @sort-change="sort">
|
||||
<el-table-column prop="name" :label="$t('commons.name')" width="250" show-overflow-tooltip/>
|
||||
<el-table-column prop="description" :label="$t('commons.description')" show-overflow-tooltip/>
|
||||
<el-table-column prop="description" :label="$t('commons.description')" show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<pre>{{scope.row.description}}</pre>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--<el-table-column prop="workspaceName" :label="$t('project.owning_workspace')"/>-->
|
||||
<el-table-column
|
||||
sortable
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="批量编辑用例"
|
||||
:visible.sync="dialogVisible"
|
||||
width="25%"
|
||||
class="batch-edit-dialog"
|
||||
:destroy-on-close="true"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form :model="form" label-position="right" label-width="150px" size="medium" ref="form" :rules="rules">
|
||||
<el-form-item :label="$t('test_track.case.batch_update', [size])" prop="type">
|
||||
<el-select v-model="form.type" style="width: 80%">
|
||||
<el-option label="用例等级" value="priority"/>
|
||||
<el-option label="类型" value="type"/>
|
||||
<el-option label="测试方式" value="method"/>
|
||||
<el-option label="维护人" value="maintainer"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="更新后属性值为" prop="value">
|
||||
<el-select v-model="form.value" style="width: 80%">
|
||||
<el-option label="值1" value="value1"/>
|
||||
<el-option label="值2" value="value2"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
@cancel="dialogVisible = false"
|
||||
@confirm="submit('form')"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "../../../common/components/MsDialogFooter";
|
||||
|
||||
export default {
|
||||
name: "BatchEdit",
|
||||
components: {
|
||||
MsDialogFooter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
form: {},
|
||||
size: 0,
|
||||
rules: {
|
||||
type: {required: true, message: "请选择属性", trigger: ['blur','change']},
|
||||
value: {required: true, message: "请选择属性对应的值", trigger: ['blur','change']}
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit(form) {
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (valid) {
|
||||
this.$emit("submit", this.form);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
open() {
|
||||
this.dialogVisible = true;
|
||||
this.size = this.$parent.selectRows.size;
|
||||
},
|
||||
handleClose() {
|
||||
this.form = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -49,8 +49,8 @@
|
|||
|
||||
.show-more-btn {
|
||||
width: 20px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,8 @@
|
|||
:total="total"/>
|
||||
|
||||
</el-card>
|
||||
|
||||
<batch-edit ref="batchEdit"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -139,6 +141,7 @@
|
|||
import {_filter, _sort} from "../../../../../common/js/utils";
|
||||
import {TEST_CASE_CONFIGS} from "../../../common/components/search/search-components";
|
||||
import ShowMoreBtn from "./ShowMoreBtn";
|
||||
import BatchEdit from "./BatchEdit";
|
||||
|
||||
export default {
|
||||
name: "TestCaseList",
|
||||
|
@ -149,7 +152,14 @@
|
|||
MethodTableItem,
|
||||
TypeTableItem,
|
||||
PriorityTableItem,
|
||||
MsCreateBox, TestCaseImport, TestCaseExport, MsTablePagination, NodeBreadcrumb, MsTableHeader, ShowMoreBtn
|
||||
MsCreateBox,
|
||||
TestCaseImport,
|
||||
TestCaseExport,
|
||||
MsTablePagination,
|
||||
NodeBreadcrumb,
|
||||
MsTableHeader,
|
||||
ShowMoreBtn,
|
||||
BatchEdit
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -326,6 +336,7 @@
|
|||
this.selectRows.add(row);
|
||||
}
|
||||
|
||||
// todo
|
||||
if (this.selectRows.size > 1) {
|
||||
Array.from(this.selectRows).forEach(row => {
|
||||
this.$set(row, "showMore", true);
|
||||
|
@ -393,7 +404,7 @@
|
|||
this.initTableData();
|
||||
},
|
||||
handleClickStop() {
|
||||
console.log("click stop");
|
||||
this.$refs.batchEdit.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,6 +266,7 @@ export default {
|
|||
stop_tips: 'A <strong>Graceful shutdown</strong> will archive the JTL files and then stop the servers.',
|
||||
force_stop_btn: 'Terminating',
|
||||
stop_btn: 'Graceful shutdown',
|
||||
not_exist: "Test report does not exist",
|
||||
},
|
||||
load_test: {
|
||||
operating: 'Operating',
|
||||
|
@ -476,6 +477,7 @@ export default {
|
|||
detail: "Report detail",
|
||||
delete: "Delete report",
|
||||
running: "The test is running",
|
||||
not_exist: "Test report does not exist",
|
||||
},
|
||||
test_track: {
|
||||
test_track: "Track",
|
||||
|
@ -531,6 +533,7 @@ export default {
|
|||
relate_test: "Relate test",
|
||||
relate_test_not_find: 'The associated test does not exist, please check the test case',
|
||||
batch_handle: 'Batch processing (select {0} item)',
|
||||
batch_update: 'Update the attributes of {0} cases',
|
||||
import: {
|
||||
import: "Import test case",
|
||||
case_import: "Import test case",
|
||||
|
|
|
@ -264,6 +264,7 @@ export default {
|
|||
stop_tips: '<strong>停止</strong>测试会结束当前测试并保留报告数据',
|
||||
force_stop_btn: '强制停止',
|
||||
stop_btn: '停止',
|
||||
not_exist: "测试报告不存在",
|
||||
},
|
||||
load_test: {
|
||||
operating: '操作',
|
||||
|
@ -475,6 +476,7 @@ export default {
|
|||
detail: "报告详情",
|
||||
delete: "删除报告",
|
||||
running: "测试执行中",
|
||||
not_exist: "测试报告不存在",
|
||||
},
|
||||
test_track: {
|
||||
test_track: "测试跟踪",
|
||||
|
@ -531,6 +533,7 @@ export default {
|
|||
relate_test: "关联测试",
|
||||
relate_test_not_find: '关联的测试不存在,请检查用例',
|
||||
batch_handle: '批量处理 (选中{0}项)',
|
||||
batch_update: '更新{0}个用例的属性',
|
||||
import: {
|
||||
import: "导入用例",
|
||||
case_import: "导入测试用例",
|
||||
|
|
|
@ -264,6 +264,7 @@ export default {
|
|||
stop_tips: '<strong>停止</strong>測試會結束當前測試並保留報告數據',
|
||||
force_stop_btn: '強制停止',
|
||||
stop_btn: '停止',
|
||||
not_exist: "測試報告不存在",
|
||||
},
|
||||
load_test: {
|
||||
operating: '操作',
|
||||
|
@ -475,6 +476,7 @@ export default {
|
|||
detail: "報告詳情",
|
||||
delete: "刪除報告",
|
||||
running: "測試執行中",
|
||||
not_exist: "測試報告不存在",
|
||||
},
|
||||
test_track: {
|
||||
test_track: "測試跟踪",
|
||||
|
@ -530,6 +532,7 @@ export default {
|
|||
relate_test: "關聯測試",
|
||||
relate_test_not_find: '關聯的測試不存在,請檢查用例',
|
||||
batch_handle: '批量處理 (選中{0}項)',
|
||||
batch_update: '更新{0}個用例的屬性',
|
||||
import: {
|
||||
import: "導入用例",
|
||||
case_import: "導入測試用例",
|
||||
|
|
Loading…
Reference in New Issue