Merge remote-tracking branch 'origin/master'

This commit is contained in:
q4speed 2020-08-25 17:48:13 +08:00
commit 54f025e6a2
7 changed files with 699 additions and 675 deletions

View File

@ -15,35 +15,35 @@
</el-input> </el-input>
<el-button type="primary" plain :disabled="isReadOnly" @click="saveTest"> <el-button type="primary" plain :disabled="isReadOnly" @click="saveTest">
{{$t('commons.save')}} {{ $t('commons.save') }}
</el-button> </el-button>
<el-button type="primary" plain :disabled="isReadOnly" <el-button type="primary" plain :disabled="isReadOnly"
@click="saveRunTest"> @click="saveRunTest">
{{$t('load_test.save_and_run')}} {{ $t('load_test.save_and_run') }}
</el-button> </el-button>
<!-- <el-button :disabled="isReadOnly" type="primary" plain v-if="isShowRun" @click="runTest">--> <!-- <el-button :disabled="isReadOnly" type="primary" plain v-if="isShowRun" @click="runTest">-->
<!-- {{$t('api_test.run')}}--> <!-- {{$t('api_test.run')}}-->
<!-- </el-button>--> <!-- </el-button>-->
<el-button :disabled="isReadOnly" type="warning" plain @click="cancel">{{$t('commons.cancel')}} <el-button :disabled="isReadOnly" type="warning" plain @click="cancel">{{ $t('commons.cancel') }}
</el-button> </el-button>
<el-dropdown trigger="click" @command="handleCommand"> <el-dropdown trigger="click" @command="handleCommand">
<el-button class="el-dropdown-link more" icon="el-icon-more" plain/> <el-button class="el-dropdown-link more" icon="el-icon-more" plain/>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item command="report"> <el-dropdown-item command="report">
{{$t('api_report.title')}} {{ $t('api_report.title') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="performance" :disabled="create || isReadOnly"> <el-dropdown-item command="performance" :disabled="create || isReadOnly">
{{$t('api_test.create_performance_test')}} {{ $t('api_test.create_performance_test') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="export" :disabled="isReadOnly || create"> <el-dropdown-item command="export" :disabled="isReadOnly || create">
{{$t('api_test.export_config')}} {{ $t('api_test.export_config') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="import" :disabled="isReadOnly"> <el-dropdown-item command="import" :disabled="isReadOnly">
{{$t('api_test.api_import.label')}} {{ $t('api_test.api_import.label') }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
@ -52,10 +52,12 @@
<ms-api-report-dialog :test-id="id" ref="reportDialog"/> <ms-api-report-dialog :test-id="id" ref="reportDialog"/>
<ms-schedule-config :schedule="test.schedule" :is-read-only="isReadOnly" :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-row>
</el-header> </el-header>
<ms-api-scenario-config :debug-report-id="debugReportId" @runDebug="runDebug" :is-read-only="isReadOnly" :scenarios="test.scenarioDefinition" :project-id="test.projectId" ref="config"/> <ms-api-scenario-config :debug-report-id="debugReportId" @runDebug="runDebug" :is-read-only="isReadOnly"
:scenarios="test.scenarioDefinition" :project-id="test.projectId" ref="config"/>
</el-container> </el-container>
</el-card> </el-card>
</div> </div>
@ -63,16 +65,17 @@
</template> </template>
<script> <script>
import MsApiScenarioConfig from "./components/ApiScenarioConfig"; import MsApiScenarioConfig from "./components/ApiScenarioConfig";
import {Test} from "./model/ScenarioModel" import {Test} 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} 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 {getUUID} from "../../../../common/js/utils";
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
export default { export default {
name: "MsApiTestConfig", name: "MsApiTestConfig",
components: {ApiImport, MsScheduleConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig}, components: {ApiImport, MsScheduleConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig},
@ -155,7 +158,7 @@
let jmx = this.test.toJMX(); let jmx = this.test.toJMX();
let blob = new Blob([jmx.xml], {type: "application/octet-stream"}); let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
let file = new File([blob], jmx.name); let file = new File([blob], jmx.name);
this.result = this.$fileUpload(url, file, bodyFiles, this.test,response => { this.result = this.$fileUpload(url, file, bodyFiles, this.test, response => {
if (callback) callback(); if (callback) callback();
this.create = false; this.create = false;
this.resetBodyFile(); this.resetBodyFile();
@ -169,6 +172,8 @@
path: '/api/test/edit?id=' + this.test.id path: '/api/test/edit?id=' + this.test.id
}) })
} }
// 广 head
ApiEvent.$emit(LIST_CHANGE);
}) })
}, },
runTest() { runTest() {
@ -185,6 +190,8 @@
this.save(() => { this.save(() => {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
this.runTest(); this.runTest();
// 广 head
ApiEvent.$emit(LIST_CHANGE);
}) })
}, },
getBodyUploadFiles() { getBodyUploadFiles() {
@ -193,7 +200,7 @@
this.test.scenarioDefinition.forEach(scenario => { this.test.scenarioDefinition.forEach(scenario => {
scenario.requests.forEach(request => { scenario.requests.forEach(request => {
if (request.body) { if (request.body) {
request.body.kvs.forEach( param => { request.body.kvs.forEach(param => {
if (param.files) { if (param.files) {
param.files.forEach(item => { param.files.forEach(item => {
if (item.file) { if (item.file) {
@ -217,7 +224,7 @@
this.test.scenarioDefinition.forEach(scenario => { this.test.scenarioDefinition.forEach(scenario => {
scenario.requests.forEach(request => { scenario.requests.forEach(request => {
if (request.body) { if (request.body) {
request.body.kvs.forEach( param => { request.body.kvs.forEach(param => {
if (param.files) { if (param.files) {
param.files.forEach(item => { param.files.forEach(item => {
if (item.file) { if (item.file) {
@ -302,7 +309,7 @@
let jmx = runningTest.toJMX(); let jmx = runningTest.toJMX();
let blob = new Blob([jmx.xml], {type: "application/octet-stream"}); let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
let file = new File([blob], jmx.name); let file = new File([blob], jmx.name);
this.$fileUpload(url, file, null, this.test,response => { this.$fileUpload(url, file, null, this.test, response => {
this.debugReportId = response.data; this.debugReportId = response.data;
}); });
} }
@ -311,26 +318,26 @@
created() { created() {
this.init(); this.init();
} }
} }
</script> </script>
<style scoped> <style scoped>
.test-container { .test-container {
height: calc(100vh - 150px); height: calc(100vh - 150px);
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>

View File

@ -7,7 +7,7 @@
<el-col :span="4" class="script-index"> <el-col :span="4" class="script-index">
<div class="template-title">{{$t('api_test.request.processor.code_template')}}</div> <div class="template-title">{{$t('api_test.request.processor.code_template')}}</div>
<div v-for="(template, index) in codeTemplates" :key="index" class="code-template"> <div v-for="(template, index) in codeTemplates" :key="index" class="code-template">
<el-link @click="addTemplate(template)">{{template.title}}</el-link> <el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
</div> </div>
<div class="document-url"> <div class="document-url">
<el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor" type="primary">{{$t('commons.reference_documentation')}}</el-link> <el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor" type="primary">{{$t('commons.reference_documentation')}}</el-link>
@ -29,23 +29,26 @@
codeTemplates: [ codeTemplates: [
{ {
title: this.$t('api_test.request.processor.code_template_get_variable'), title: this.$t('api_test.request.processor.code_template_get_variable'),
value: 'vars.get("variable_name");' value: 'vars.get("variable_name");',
}, },
{ {
title: this.$t('api_test.request.processor.code_template_set_variable'), title: this.$t('api_test.request.processor.code_template_set_variable'),
value: 'vars.put("variable_name", "variable_value");' value: 'vars.put("variable_name", "variable_value");',
}, },
{ {
title: this.$t('api_test.request.processor.code_template_get_response_header'), title: this.$t('api_test.request.processor.code_template_get_response_header'),
value: 'prev.getResponseHeaders();' value: 'prev.getResponseHeaders();',
disabled: this.isPreProcessor
}, },
{ {
title: this.$t('api_test.request.processor.code_template_get_response_code'), title: this.$t('api_test.request.processor.code_template_get_response_code'),
value: 'prev.getResponseCode();' value: 'prev.getResponseCode();',
disabled: this.isPreProcessor
}, },
{ {
title: this.$t('api_test.request.processor.code_template_get_response_result'), title: this.$t('api_test.request.processor.code_template_get_response_result'),
value: 'prev.getResponseDataAsString();' value: 'prev.getResponseDataAsString();',
disabled: this.isPreProcessor
} }
], ],
isCodeEditAlive: true isCodeEditAlive: true
@ -61,6 +64,10 @@
}, },
beanShellProcessor: { beanShellProcessor: {
type: Object, type: Object,
},
isPreProcessor: {
type: Boolean,
default: false
} }
}, },
methods: { methods: {

View File

@ -68,7 +68,7 @@
<ms-api-extract :is-read-only="isReadOnly" :extract="request.extract"/> <ms-api-extract :is-read-only="isReadOnly" :extract="request.extract"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_test.request.processor.pre_exec_script')" name="beanShellPreProcessor"> <el-tab-pane :label="$t('api_test.request.processor.pre_exec_script')" name="beanShellPreProcessor">
<ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPreProcessor"/> <ms-bean-shell-processor :is-pre-processor="true" :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPreProcessor"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_test.request.processor.post_exec_script')" name="beanShellPostProcessor"> <el-tab-pane :label="$t('api_test.request.processor.post_exec_script')" name="beanShellPostProcessor">
<ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPostProcessor"/> <ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPostProcessor"/>

View File

@ -60,6 +60,7 @@ import MsContainer from "../../common/components/MsContainer";
import MsMainContainer from "../../common/components/MsMainContainer"; import MsMainContainer from "../../common/components/MsMainContainer";
import {checkoutTestManagerOrTestUser} from "../../../../common/js/utils"; import {checkoutTestManagerOrTestUser} from "../../../../common/js/utils";
import MsScheduleConfig from "../../common/components/MsScheduleConfig"; import MsScheduleConfig from "../../common/components/MsScheduleConfig";
import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent";
export default { export default {
name: "EditPerformanceTestPlan", name: "EditPerformanceTestPlan",
@ -172,6 +173,8 @@ export default {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
this.$refs.advancedConfig.cancelAllEdit(); this.$refs.advancedConfig.cancelAllEdit();
this.$router.push({path: '/performance/test/all'}) this.$router.push({path: '/performance/test/all'})
// 广 head
PerformanceEvent.$emit(LIST_CHANGE);
}); });
}, },
saveAndRun() { saveAndRun() {
@ -187,6 +190,8 @@ export default {
this.result = this.$post(this.runPath, {id: this.testPlan.id, triggerMode: 'MANUAL'}, (response) => { this.result = this.$post(this.runPath, {id: this.testPlan.id, triggerMode: 'MANUAL'}, (response) => {
let reportId = response.data; let reportId = response.data;
this.$router.push({path: '/performance/report/view/' + reportId}) this.$router.push({path: '/performance/report/view/' + reportId})
// 广 head
PerformanceEvent.$emit(LIST_CHANGE);
}) })
}); });
}, },

View File

@ -105,12 +105,12 @@
</el-col> </el-col>
<el-col :span="9" :offset="1" v-if="form.testId=='other'"> <el-col :span="9" :offset="1" v-if="form.testId=='other'">
<el-form-item :label="$t('test_track.case.test_name')" :label-width="formLabelWidth" prop="testId"> <el-form-item :label="$t('test_track.case.test_name')" :label-width="formLabelWidth" prop="testId">
<el-input v-model="form.otherTestName" :placeholder="$t('test_track.case.input_test_case')" ></el-input> <el-input v-model="form.otherTestName" :placeholder="$t('test_track.case.input_test_case')"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row style="margin-top: 15px;"> <el-row style="margin-top: 15px;">
<el-col :offset="2">{{$t('test_track.case.prerequisite')}}:</el-col> <el-col :offset="2">{{ $t('test_track.case.prerequisite') }}:</el-col>
</el-row> </el-row>
<el-row type="flex" justify="center" style="margin-top: 10px;"> <el-row type="flex" justify="center" style="margin-top: 10px;">
<el-col :span="20"> <el-col :span="20">
@ -125,7 +125,7 @@
</el-row> </el-row>
<el-row v-if="form.method && form.method != 'auto'" style="margin-bottom: 10px"> <el-row v-if="form.method && form.method != 'auto'" style="margin-bottom: 10px">
<el-col :offset="2">{{$t('test_track.case.steps')}}:</el-col> <el-col :offset="2">{{ $t('test_track.case.steps') }}:</el-col>
</el-row> </el-row>
<el-row v-if="form.method && form.method != 'auto'" type="flex" justify="center"> <el-row v-if="form.method && form.method != 'auto'" type="flex" justify="center">
@ -187,7 +187,7 @@
</el-row> </el-row>
<el-row style="margin-top: 15px;margin-bottom: 10px"> <el-row style="margin-top: 15px;margin-bottom: 10px">
<el-col :offset="2">{{$t('commons.remark')}}:</el-col> <el-col :offset="2">{{ $t('commons.remark') }}:</el-col>
</el-row> </el-row>
<el-row type="flex" justify="center"> <el-row type="flex" justify="center">
<el-col :span="20"> <el-col :span="20">
@ -222,11 +222,12 @@
<script> <script>
import {WORKSPACE_ID, TokenKey} from '../../../../../common/js/constants'; import {TokenKey, WORKSPACE_ID} from '../../../../../common/js/constants';
import MsDialogFooter from '../../../common/components/MsDialogFooter' import MsDialogFooter from '../../../common/components/MsDialogFooter'
import {listenGoBack, removeGoBackListener, removeListenGoBack} from "../../../../../common/js/utils"; import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils";
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
export default { export default {
name: "TestCaseEdit", name: "TestCaseEdit",
components: {MsDialogFooter}, components: {MsDialogFooter},
data() { data() {
@ -242,7 +243,7 @@
method: '', method: '',
prerequisite: '', prerequisite: '',
testId: '', testId: '',
otherTestName:'', otherTestName: '',
steps: [{ steps: [{
num: 1, num: 1,
desc: '', desc: '',
@ -386,6 +387,8 @@
} }
this.dialogFormVisible = false; this.dialogFormVisible = false;
this.$emit("refresh"); this.$emit("refresh");
// 广 head
TrackEvent.$emit(LIST_CHANGE);
}); });
} }
} else { } else {
@ -450,7 +453,7 @@
if (this.currentProject && this.form.type != '' && this.form.type != 'functional') { if (this.currentProject && this.form.type != '' && this.form.type != 'functional') {
this.result = this.$get('/' + this.form.type + '/list/' + this.currentProject.id, response => { this.result = this.$get('/' + this.form.type + '/list/' + this.currentProject.id, response => {
this.testOptions = response.data; this.testOptions = response.data;
this.testOptions.unshift({id:'other',name:this.$t('test_track.case.other')}) this.testOptions.unshift({id: 'other', name: this.$t('test_track.case.other')})
}); });
} }
}, },
@ -496,7 +499,7 @@
this.form.prerequisite = ''; this.form.prerequisite = '';
this.form.remark = ''; this.form.remark = '';
this.form.testId = ''; this.form.testId = '';
this.form.testName=''; this.form.testName = '';
this.form.steps = [{ this.form.steps = [{
num: 1, num: 1,
desc: '', desc: '',
@ -507,17 +510,17 @@
} }
} }
} }
} }
</script> </script>
<style scoped> <style scoped>
.el-switch { .el-switch {
margin-bottom: 10px; margin-bottom: 10px;
} }
.case-name { .case-name {
width: 194px; width: 194px;
} }
</style> </style>

View File

@ -108,7 +108,6 @@ export default {
methods: { methods: {
handleDragEnd(draggingNode, dropNode, dropType, ev) { handleDragEnd(draggingNode, dropNode, dropType, ev) {
let param = this.buildParam(draggingNode, dropNode, dropType); let param = this.buildParam(draggingNode, dropNode, dropType);
console.log(this.treeNodes);
this.$post("/case/node/drag", param, () => { this.$post("/case/node/drag", param, () => {
draggingNode.data.level = param.level; draggingNode.data.level = param.level;
this.refreshTable(); this.refreshTable();

View File

@ -92,12 +92,12 @@
<div class="dialog-footer"> <div class="dialog-footer">
<el-button <el-button
@click="dialogFormVisible = false"> @click="dialogFormVisible = false">
{{$t('test_track.cancel')}} {{ $t('test_track.cancel') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@click="savePlan"> @click="savePlan">
{{$t('test_track.confirm')}} {{ $t('test_track.confirm') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@ -110,11 +110,12 @@
<script> <script>
import {WORKSPACE_ID} from '../../../../../common/js/constants'; import {WORKSPACE_ID} from '../../../../../common/js/constants';
import TestPlanStatusButton from "../common/TestPlanStatusButton"; import TestPlanStatusButton from "../common/TestPlanStatusButton";
import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils"; import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils";
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
export default { export default {
name: "TestPlanEdit", name: "TestPlanEdit",
components: {TestPlanStatusButton}, components: {TestPlanStatusButton},
data() { data() {
@ -127,15 +128,15 @@
stage: '', stage: '',
description: '' description: ''
}, },
rules:{ rules: {
name :[ name: [
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'}, {required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
{ max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur' } {max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
], ],
projectId :[{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}], projectId: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
principal :[{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}], principal: [{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
stage :[{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}], stage: [{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
description :[{ max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}] description: [{max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}]
}, },
formLabelWidth: "120px", formLabelWidth: "120px",
operationType: '', operationType: '',
@ -149,7 +150,7 @@
this.getProjects(); this.getProjects();
this.setPrincipalOptions(); this.setPrincipalOptions();
this.operationType = 'add'; this.operationType = 'add';
if(testPlan){ if (testPlan) {
// //
this.operationType = 'edit'; this.operationType = 'edit';
let tmp = {}; let tmp = {};
@ -159,7 +160,7 @@
listenGoBack(this.close); listenGoBack(this.close);
this.dialogFormVisible = true; this.dialogFormVisible = true;
}, },
savePlan(){ savePlan() {
this.$refs['planFrom'].validate((valid) => { this.$refs['planFrom'].validate((valid) => {
if (valid) { if (valid) {
let param = {}; let param = {};
@ -174,6 +175,8 @@
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
this.dialogFormVisible = false; this.dialogFormVisible = false;
this.$emit("refresh"); this.$emit("refresh");
// 广 head
TrackEvent.$emit(LIST_CHANGE);
}); });
} else { } else {
return false; return false;
@ -191,7 +194,7 @@
}, },
setPrincipalOptions() { setPrincipalOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID); let workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/user/ws/member/tester/list', {workspaceId:workspaceId}, response => { this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
this.principalOptions = response.data; this.principalOptions = response.data;
}); });
}, },
@ -219,7 +222,7 @@
} }
} }
} }
} }
</script> </script>
<style scoped> <style scoped>