feat(接口自动化): 获取实时执行步骤结果

This commit is contained in:
fit2-zhao 2021-06-25 19:06:06 +08:00 committed by fit2-zhao
parent fe677b0b40
commit 6743dac777
11 changed files with 820 additions and 577 deletions

View File

@ -62,4 +62,9 @@ public class APIScenarioReportController {
return resultService.getResult(reportId); return resultService.getResult(reportId);
} }
@GetMapping("/remove/real/{reportId}")
public void removeRealReport(@PathVariable String reportId) {
resultService.delete(reportId);
}
} }

View File

@ -38,8 +38,10 @@ public class MsResultService {
if (testResult == null) { if (testResult == null) {
testResult = new TestResult(); testResult = new TestResult();
} }
if(result.getResponseCode().equals(MsResultCollector.TEST_END)){ if (result.getResponseCode().equals(MsResultCollector.TEST_END)) {
testResult.setEnd(true);
this.cache.put(key, testResult);
return;
} }
testResult.setTestId(key); testResult.setTestId(key);
testResult.setConsole(getJmeterLogger(key, false)); testResult.setConsole(getJmeterLogger(key, false));
@ -50,7 +52,7 @@ public class MsResultService {
testResult.getScenarios().addAll(scenarios.values()); testResult.getScenarios().addAll(scenarios.values());
testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId)); testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId));
System.out.println(key + "=======" + result.getURL());
this.cache.put(key, testResult); this.cache.put(key, testResult);
} }

View File

@ -136,31 +136,29 @@
<el-col :span="3" class="ms-col-one ms-font"> <el-col :span="3" class="ms-col-one ms-font">
<el-checkbox v-model="onSampleError">{{ $t('commons.failure_continues') }}</el-checkbox> <el-checkbox v-model="onSampleError">{{ $t('commons.failure_continues') }}</el-checkbox>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="8">
<env-popover :disabled="scenarioDefinition.length < 1" :env-map="projectEnvMap" <div style=" float: right">
:project-ids="projectIds" @setProjectEnvMap="setProjectEnvMap" :result="envResult" <env-popover :disabled="scenarioDefinition.length < 1" :env-map="projectEnvMap"
:show-config-button-with-out-permission="showConfigButtonWithOutPermission" :project-ids="projectIds" @setProjectEnvMap="setProjectEnvMap" :result="envResult"
:isReadOnly="scenarioDefinition.length < 1" @showPopover="showPopover" :show-config-button-with-out-permission="showConfigButtonWithOutPermission"
:project-list="projectList" ref="envPopover"/> :isReadOnly="scenarioDefinition.length < 1" @showPopover="showPopover"
</el-col> :project-list="projectList" ref="envPopover" style="margin-right: 10px"/>
<el-col :span="4"> <el-dropdown split-button type="primary" @click="runDebug" style="margin-right: 10px" size="mini" @command="handleCommand" v-if="!debugLoading">
<!-- <el-dropdown split-button type="primary" @click="runDebug" style="margin-right: 10px" size="mini" @command="handleCommand">--> {{ $t('api_test.request.debug') }}
<!-- {{ $t('api_test.request.debug') }}--> <el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-menu slot="dropdown">--> <el-dropdown-item>{{ $t('test_track.case.steps') }}</el-dropdown-item>
<!-- <el-dropdown-item>{{ $t('api_test.run') }}</el-dropdown-item>--> </el-dropdown-menu>
<!-- </el-dropdown-menu>--> </el-dropdown>
<!-- </el-dropdown>--> <el-button icon="el-icon-loading" size="mini" type="primary" :disabled="debug" v-else>执行中</el-button>
<el-button :disabled="scenarioDefinition.length < 1" size="mini" type="primary" v-prevent-re-click <el-tooltip class="item" effect="dark" :content="$t('commons.refresh')" placement="top-start">
@click="runDebug">{{ $t('api_test.request.debug') }} <el-button :disabled="scenarioDefinition.length < 1" size="mini" icon="el-icon-refresh"
</el-button> v-prevent-re-click @click="getApiScenario"></el-button>
<el-tooltip class="item" effect="dark" :content="$t('commons.refresh')" placement="right-start"> </el-tooltip>
<el-button :disabled="scenarioDefinition.length < 1" size="mini" icon="el-icon-refresh" <el-tooltip class="item" effect="dark" :content="$t('commons.full_screen_editing')"
v-prevent-re-click @click="getApiScenario"></el-button> placement="top-start">
</el-tooltip> <font-awesome-icon class="alt-ico" :icon="['fa', 'expand-alt']" size="lg" @click="fullScreen"/>
<el-tooltip class="item" effect="dark" :content="$t('commons.full_screen_editing')" </el-tooltip>
placement="top-start"> </div>
<font-awesome-icon class="alt-ico" :icon="['fa', 'expand-alt']" size="lg" @click="fullScreen"/>
</el-tooltip>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
@ -179,7 +177,7 @@
<font-awesome-icon class="ms-open-btn" :icon="['fas', 'toggle-on']" v-prevent-re-click @click="disableAll"/> <font-awesome-icon class="ms-open-btn" :icon="['fas', 'toggle-on']" v-prevent-re-click @click="disableAll"/>
</el-tooltip> </el-tooltip>
<div class="ms-debug-result" v-if="debug"> <div class="ms-debug-result" v-if="debug">
354 ms 请求 10 成功 8 失败 2 {{ reqTotalTime }} ms 请求 {{ reqTotal }} 成功 {{ reqSuccess }} 失败 {{ reqError }}
</div> </div>
<el-tree node-key="resourceId" :props="props" :data="scenarioDefinition" class="ms-tree" <el-tree node-key="resourceId" :props="props" :data="scenarioDefinition" class="ms-tree"
:default-expanded-keys="expandedNode" :default-expanded-keys="expandedNode"
@ -256,15 +254,17 @@
:projectIds.sync="projectIds" :projectList="projectList" :projectIds.sync="projectIds" :projectList="projectList"
:scenarioDefinition="scenarioDefinition" :enableCookieShare="enableCookieShare" :scenarioDefinition="scenarioDefinition" :enableCookieShare="enableCookieShare"
:onSampleError="onSampleError" :onSampleError="onSampleError"
:execDebug="stopDebug"
:isFullUrl.sync="isFullUrl" @closePage="close" @unFullScreen="unFullScreen" :isFullUrl.sync="isFullUrl" @closePage="close" @unFullScreen="unFullScreen"
@showAllBtn="showAllBtn" @runDebug="runDebug" @setProjectEnvMap="setProjectEnvMap" @showAllBtn="showAllBtn" @runDebug="runDebug" @handleCommand="handleCommand" @setProjectEnvMap="setProjectEnvMap"
@showScenarioParameters="showScenarioParameters" @showScenarioParameters="showScenarioParameters"
@setCookieShare="setCookieShare" @setSampleError="setSampleError" @setCookieShare="setCookieShare" @setSampleError="setSampleError"
ref="maximizeHeader"/> ref="maximizeHeader"/>
</template> </template>
<maximize-scenario :scenario-definition="scenarioDefinition" :envMap="projectEnvMap" :moduleOptions="moduleOptions" <maximize-scenario :scenario-definition="scenarioDefinition" :envMap="projectEnvMap" :moduleOptions="moduleOptions"
:currentScenario="currentScenario" :type="type" :stepReEnable="stepEnable" ref="maximizeScenario" @openScenario="openScenario"/> :req-error="reqError" :req-success="reqSuccess" :req-total="reqTotal" :req-total-time="reqTotalTime"
:currentScenario="currentScenario" :type="type" :debug="debug" :reloadDebug="reloadDebug" :stepReEnable="stepEnable" ref="maximizeScenario" @openScenario="openScenario"/>
</ms-drawer> </ms-drawer>
<ms-change-history ref="changeHistory"/> <ms-change-history ref="changeHistory"/>
@ -274,16 +274,7 @@
<script> <script>
import {API_STATUS, PRIORITY} from "../../definition/model/JsonData"; import {API_STATUS, PRIORITY} from "../../definition/model/JsonData";
import {WORKSPACE_ID} from '@/common/js/constants'; import {buttons, setComponent} from './menu/Menu';
import {
Assertions,
ConstantTimer,
Extract,
IfController,
JSR223Processor,
LoopController,
TransactionController
} from "../../definition/model/ApiTestModel";
import {parseEnvironment} from "../../definition/model/EnvironmentModel"; import {parseEnvironment} from "../../definition/model/EnvironmentModel";
import {ELEMENT_TYPE, ELEMENTS} from "./Setting"; import {ELEMENT_TYPE, ELEMENTS} from "./Setting";
import MsApiCustomize from "./ApiCustomize"; import MsApiCustomize from "./ApiCustomize";
@ -402,12 +393,21 @@ export default {
loading: false loading: false
}, },
debug: false, debug: false,
debugLoading: false,
reqTotal: 0,
reqSuccess: 0,
reqError: 0,
reqTotalTime: 0,
reloadDebug: "",
stopDebug: "",
} }
}, },
created() { created() {
if (!this.currentScenario.apiScenarioModuleId) { if (!this.currentScenario.apiScenarioModuleId) {
this.currentScenario.apiScenarioModuleId = ""; this.currentScenario.apiScenarioModuleId = "";
} }
this.debug = false;
this.debugLoading = false;
this.operatingElements = ELEMENTS.get("ALL"); this.operatingElements = ELEMENTS.get("ALL");
this.getWsProjects(); this.getWsProjects();
this.getMaintainerOptions(); this.getMaintainerOptions();
@ -417,147 +417,106 @@ export default {
}, },
directives: {OutsideClick}, directives: {OutsideClick},
computed: { computed: {
buttons() { buttons,
let buttons = [
{
title: this.$t('api_test.definition.request.extract_param'),
show: this.showButton("Extract"),
titleColor: "#015478",
titleBgColor: "#E6EEF2",
icon: "colorize",
click: () => {
this.addComponent('Extract')
}
},
{
title: this.$t('api_test.definition.request.post_script'),
show: this.showButton("JSR223PostProcessor"),
titleColor: "#783887",
titleBgColor: "#F2ECF3",
icon: "skip_next",
click: () => {
this.addComponent('JSR223PostProcessor')
}
},
{
title: this.$t('api_test.definition.request.pre_script'),
show: this.showButton("JSR223PreProcessor"),
titleColor: "#B8741A",
titleBgColor: "#F9F1EA",
icon: "skip_previous",
click: () => {
this.addComponent('JSR223PreProcessor')
}
},
{
title: this.$t('api_test.automation.customize_script'),
show: this.showButton("JSR223Processor"),
titleColor: "#7B4D12",
titleBgColor: "#F1EEE9",
icon: "code",
click: () => {
this.addComponent('JSR223Processor')
}
},
{
title: this.$t('api_test.automation.if_controller'),
show: this.showButton("IfController"),
titleColor: "#E6A23C",
titleBgColor: "#FCF6EE",
icon: "alt_route",
click: () => {
this.addComponent('IfController')
}
},
{
title: this.$t('api_test.automation.loop_controller'),
show: this.showButton("LoopController"),
titleColor: "#02A7F0",
titleBgColor: "#F4F4F5",
icon: "next_plan",
click: () => {
this.addComponent('LoopController')
}
},
{
title: this.$t('api_test.automation.transcation_controller'),
show: this.showButton("TransactionController"),
titleColor: "#6D317C",
titleBgColor: "#F4F4F5",
icon: "alt_route",
click: () => {
this.addComponent('TransactionController')
}
},
{
title: this.$t('api_test.automation.wait_controller'),
show: this.showButton("ConstantTimer"),
titleColor: "#67C23A",
titleBgColor: "#F2F9EE",
icon: "access_time",
click: () => {
this.addComponent('ConstantTimer')
}
},
{
title: this.$t('api_test.definition.request.assertions_rule'),
show: this.showButton("Assertions"),
titleColor: "#A30014",
titleBgColor: "#F7E6E9",
icon: "next_plan",
click: () => {
this.addComponent('Assertions')
}
},
{
title: this.$t('api_test.automation.customize_req'),
show: this.showButton("CustomizeReq"),
titleColor: "#008080",
titleBgColor: "#EBF2F2",
icon: "tune",
click: () => {
this.addComponent('CustomizeReq')
}
},
{
title: this.$t('api_test.automation.scenario_import'),
show: this.showButton("scenario"),
titleColor: "#606266",
titleBgColor: "#F4F4F5",
icon: "movie",
click: () => {
this.addComponent('scenario')
}
},
{
title: this.$t('api_test.automation.api_list_import'),
show: this.showButton("HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler"),
titleColor: "#F56C6C",
titleBgColor: "#FCF1F1",
icon: "api",
click: this.apiListImport
}
];
return buttons.filter(btn => btn.show);
},
projectId() { projectId() {
return getCurrentProjectID(); return getCurrentProjectID();
}, },
}, },
methods: { methods: {
clearDebug() {
this.reqError = 0;
this.reqTotalTime = 0;
this.reqTotal = 0;
this.reqSuccess = 0;
},
editParent(node, status) {
if (!status) {
node.data.code = "error";
}
node.data.debug = true;
if (node.parent && node.parent.data && node.parent.data.id) {
this.editParent(node.parent, status);
}
},
findNodeChild(arr, name, index, status) {
arr.forEach(item => {
if (item.data.name === name && item.data.index === index) {
this.editParent(item.parent, status);
}
if (item.childNodes && item.childNodes.length > 0) {
this.findNodeChild(item.childNodes, name, index, status);
}
})
},
findNode(name, index, status) {
if (this.$refs.stepTree && this.$refs.stepTree.root) {
this.$refs.stepTree.root.childNodes.forEach(item => {
if (item.childNodes && item.childNodes.length > 0) {
this.findNodeChild(item.childNodes, name, index, status);
}
})
}
},
getReport() { getReport() {
if (this.debug) { if (this.debug) {
let url = "/api/scenario/report/get/real/" + this.reportId; let url = "/api/scenario/report/get/real/" + this.reportId;
this.$get(url, response => { this.$get(url, response => {
// if (response.data && response.data.end) { if (response.data) {
// console.log(response.data); this.formatResult(response.data);
// } else { if (response.data.end) {
// setTimeout(this.getReport, 2000) this.removeReport();
// } this.debugLoading = false;
this.stopDebug = "stop";
} else {
setTimeout(this.getReport, 2000)
}
} else {
setTimeout(this.getReport, 2000)
}
}); });
} }
}, },
formatResult(res) {
let resMap = new Map;
let startTime = 99991611737506593;
let endTime = 0;
this.clearDebug();
if (res && res.scenarios) {
res.scenarios.forEach(item => {
this.reqTotal += item.requestResults.length;
if (item && item.requestResults) {
item.requestResults.forEach(req => {
req.responseResult.console = res.console;
let name = req.name.split('<->')[0];
resMap.set(req.id + name, req);
if (req.success) {
this.reqSuccess++;
} else {
this.reqError++;
}
if (req.startTime && Number(req.startTime) < startTime) {
startTime = req.startTime;
}
if (req.endTime && Number(req.endTime) > endTime) {
endTime = req.endTime;
}
})
}
})
}
if (startTime < endTime) {
this.reqTotalTime = endTime - startTime + 100;
}
this.debugResult = resMap;
this.sort();
this.reload();
this.reloadDebug = getUUID();
},
removeReport() {
let url = "/api/scenario/report/remove/real/" + this.reportId;
this.$get(url, response => {
});
},
handleCommand() { handleCommand() {
this.debug = false; this.debug = false;
/*触发执行操作*/ /*触发执行操作*/
@ -591,7 +550,6 @@ export default {
} }
}) })
}, },
openHis() { openHis() {
this.$refs.changeHistory.open(this.currentScenario.id); this.$refs.changeHistory.open(this.currentScenario.id);
}, },
@ -658,59 +616,7 @@ export default {
} }
}, },
addComponent(type) { addComponent(type) {
switch (type) { setComponent(type, this);
case ELEMENT_TYPE.IfController:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new IfController()) :
this.scenarioDefinition.push(new IfController());
break;
case ELEMENT_TYPE.ConstantTimer:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new ConstantTimer()) :
this.scenarioDefinition.push(new ConstantTimer());
break;
case ELEMENT_TYPE.JSR223Processor:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new JSR223Processor()) :
this.scenarioDefinition.push(new JSR223Processor());
break;
case ELEMENT_TYPE.JSR223PreProcessor:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new JSR223Processor({type: "JSR223PreProcessor"})) :
this.scenarioDefinition.push(new JSR223Processor({type: "JSR223PreProcessor"}));
break;
case ELEMENT_TYPE.JSR223PostProcessor:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new JSR223Processor({type: "JSR223PostProcessor"})) :
this.scenarioDefinition.push(new JSR223Processor({type: "JSR223PostProcessor"}));
break;
case ELEMENT_TYPE.Assertions:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new Assertions()) :
this.scenarioDefinition.push(new Assertions());
break;
case ELEMENT_TYPE.Extract:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new Extract()) :
this.scenarioDefinition.push(new Extract());
break;
case ELEMENT_TYPE.CustomizeReq:
this.customizeRequest = {protocol: "HTTP", type: "API", hashTree: [], referenced: 'Created', active: false};
this.customizeVisible = true;
break;
case ELEMENT_TYPE.LoopController:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new LoopController()) :
this.scenarioDefinition.push(new LoopController());
break;
case ELEMENT_TYPE.TransactionController:
this.selectedTreeNode !== undefined ? this.selectedTreeNode.hashTree.push(new TransactionController()) :
this.scenarioDefinition.push(new TransactionController());
break;
case ELEMENT_TYPE.scenario:
this.isBtnHide = true;
this.$refs.scenarioRelevance.open();
break;
default:
this.$refs.apiImport.open();
break;
}
if (this.selectedNode) {
this.selectedNode.expanded = true;
}
this.sort();
}, },
nodeClick(data, node) { nodeClick(data, node) {
if (data.referenced != 'REF' && data.referenced != 'Deleted' && !data.disabled) { if (data.referenced != 'REF' && data.referenced != 'Deleted' && !data.disabled) {
@ -763,6 +669,8 @@ export default {
// debug // debug
if (this.debugResult && this.debugResult.get(arr[i].id + arr[i].name)) { if (this.debugResult && this.debugResult.get(arr[i].id + arr[i].name)) {
arr[i].requestResult = this.debugResult.get(arr[i].id + arr[i].name); arr[i].requestResult = this.debugResult.get(arr[i].id + arr[i].name);
arr[i].debug = this.debug;
this.findNode(arr[i].name, arr[i].index, arr[i].requestResult.success);
} }
} }
}, },
@ -794,6 +702,7 @@ export default {
// debug // debug
if (this.debugResult && this.debugResult.get(this.scenarioDefinition[i].id + this.scenarioDefinition[i].name)) { if (this.debugResult && this.debugResult.get(this.scenarioDefinition[i].id + this.scenarioDefinition[i].name)) {
this.scenarioDefinition[i].requestResult = this.debugResult.get(this.scenarioDefinition[i].id + this.scenarioDefinition[i].name); this.scenarioDefinition[i].requestResult = this.debugResult.get(this.scenarioDefinition[i].id + this.scenarioDefinition[i].name);
this.scenarioDefinition[i].debug = this.debug;
} }
} }
}, },
@ -928,7 +837,10 @@ export default {
if (this.scenarioDefinition.length < 1) { if (this.scenarioDefinition.length < 1) {
return; return;
} }
// this.debug = true; this.debug = true;
this.debugLoading = true;
this.stopDebug = "";
this.clearDebug();
/*触发执行操作*/ /*触发执行操作*/
this.$refs['currentScenario'].validate((valid) => { this.$refs['currentScenario'].validate((valid) => {
if (valid) { if (valid) {
@ -955,11 +867,7 @@ export default {
onSampleError: this.onSampleError, onSampleError: this.onSampleError,
}; };
this.reportId = getUUID().substring(0, 8); this.reportId = getUUID().substring(0, 8);
// this.editScenario().then(() => {
//
// })
}) })
}) })
} }
}) })
@ -1167,10 +1075,10 @@ export default {
} }
, ,
runRefresh() { runRefresh() {
if(!this.debug) { if (!this.debug) {
this.debugVisible = true; this.debugVisible = true;
this.loading = false; this.loading = false;
}else{ } else {
this.getReport(); this.getReport();
} }
}, },
@ -1463,7 +1371,6 @@ export default {
.alt-ico:hover { .alt-ico:hover {
color: black; color: black;
cursor: pointer; cursor: pointer;
font-size: 18px;
} }
.scenario-name { .scenario-name {

View File

@ -8,6 +8,7 @@
<el-tag class="ms-left-btn" size="small" :style="{'color': color, 'background-color': backgroundColor}">{{title}}</el-tag> <el-tag class="ms-left-btn" size="small" :style="{'color': color, 'background-color': backgroundColor}">{{title}}</el-tag>
<el-tag size="mini" v-if="data.method">{{getMethod()}}</el-tag> <el-tag size="mini" v-if="data.method">{{getMethod()}}</el-tag>
</slot> </slot>
<slot name="behindHeaderLeft" v-if="!isMax"></slot>
<span> <span>
<slot name="headerLeft"> <slot name="headerLeft">
@ -25,11 +26,11 @@
</el-tooltip> </el-tooltip>
</span> </span>
</slot> </slot>
<slot name="behindHeaderLeft" v-if="!isMax"></slot>
</span> </span>
<div class="header-right" @click.stop> <div class="header-right" @click.stop>
<slot name="message"></slot> <slot name="message"></slot>
<slot name="debugStepCode"></slot>
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top" v-if="showBtn"> <el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top" v-if="showBtn">
<el-switch v-model="data.enable" class="enable-switch" size="mini" :disabled="data.disabled && !data.root" style="width: 30px"/> <el-switch v-model="data.enable" class="enable-switch" size="mini" :disabled="data.disabled && !data.root" style="width: 30px"/>
</el-tooltip> </el-tooltip>
@ -202,7 +203,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
vertical-align: middle; vertical-align: middle;
white-space: nowrap; white-space: nowrap;
width: 180px; width: 140px;
} }
.scenario-name { .scenario-name {
@ -214,7 +215,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
vertical-align: middle; vertical-align: middle;
white-space: nowrap; white-space: nowrap;
width: calc(100% - 30rem); width: calc(100% - 35rem);
} }
/deep/ .el-step__icon { /deep/ .el-step__icon {
@ -240,4 +241,5 @@
white-space: nowrap; white-space: nowrap;
width: 400px; width: 400px;
} }
</style> </style>

View File

@ -20,7 +20,13 @@
<el-tag size="mini" class="ms-tag" v-if="request.referenced ==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag> <el-tag size="mini" class="ms-tag" v-if="request.referenced ==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
<span class="ms-tag">{{ getProjectName(request.projectId) }}</span> <span class="ms-tag">{{ getProjectName(request.projectId) }}</span>
</template> </template>
<template v-slot:debugStepCode>
<el-tooltip :content="request.requestResult.responseResult.responseCode" v-if="request.debug && request.requestResult && request.requestResult.responseResult">
<span class="ms-step-debug-code" :class="request.requestResult.success?'ms-req-success':'ms-req-error'">
{{ request.requestResult.responseResult.responseCode }}
</span>
</el-tooltip>
</template>
<template v-slot:button> <template v-slot:button>
<el-tooltip :content="$t('api_test.run')" placement="top"> <el-tooltip :content="$t('api_test.run')" placement="top">
<el-button :disabled="!request.enable" @click="run" icon="el-icon-video-play" style="padding: 5px" class="ms-btn" size="mini" circle/> <el-button :disabled="!request.enable" @click="run" icon="el-icon-video-play" style="padding: 5px" class="ms-btn" size="mini" circle/>
@ -30,35 +36,34 @@
<!--请求内容--> <!--请求内容-->
<template v-slot:request> <template v-slot:request>
<legend style="width: 100%"> <legend style="width: 100%">
<customize-req-info :is-customize-req="isCustomizeReq" :request="request"/> <customize-req-info :is-customize-req="isCustomizeReq" :request="request"/>
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p> <p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
<ms-api-request-form v-if="request.protocol==='HTTP' || request.type==='HTTPSamplerProxy'" <ms-api-request-form v-if="request.protocol==='HTTP' || request.type==='HTTPSamplerProxy'"
:isShowEnable="true" :isShowEnable="true"
:referenced="true" :referenced="true"
:headers="request.headers " :headers="request.headers "
:is-read-only="isCompReadOnly" :is-read-only="isCompReadOnly"
:request="request"/> :request="request"/>
<esb-definition v-if="showXpackCompnent&&request.esbDataStruct!=null"
v-xpack <esb-definition v-if="showXpackCompnent&&request.esbDataStruct!=null"
:request="request" v-xpack
:showScript="false" :request="request"
:is-read-only="isCompReadOnly" :showScript="false"
ref="esbDefinition"/> :is-read-only="isCompReadOnly" ref="esbDefinition"/>
<!-- <ms-tcp-basis-parameters v-if="(request.protocol==='TCP'|| request.type==='TCPSampler')&& request.esbDataStruct==null "-->
<!-- :request="request"--> <ms-tcp-format-parameters v-if="(request.protocol==='TCP'|| request.type==='TCPSampler')&& request.esbDataStruct==null "
<!-- :is-read-only="isCompReadOnly"--> :is-read-only="isCompReadOnly"
<!-- :showScript="false"/>--> :show-script="false" :request="request"/>
<ms-tcp-format-parameters v-if="(request.protocol==='TCP'|| request.type==='TCPSampler')&& request.esbDataStruct==null "
:is-read-only="isCompReadOnly" <ms-sql-basis-parameters v-if="request.protocol==='SQL'|| request.type==='JDBCSampler'"
:show-script="false" :request="request"/>
<ms-sql-basis-parameters v-if="request.protocol==='SQL'|| request.type==='JDBCSampler'"
:request="request"
:is-read-only="isCompReadOnly"
:showScript="false"/>
<ms-dubbo-basis-parameters v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'|| request.type==='DubboSampler'"
:request="request" :request="request"
:is-read-only="isCompReadOnly" :is-read-only="isCompReadOnly"
:showScript="false"/> :showScript="false"/>
<ms-dubbo-basis-parameters v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'|| request.type==='DubboSampler'"
:request="request"
:is-read-only="isCompReadOnly"
:showScript="false"/>
</legend> </legend>
</template> </template>
<!-- 执行结果内容 --> <!-- 执行结果内容 -->
@ -94,8 +99,7 @@
<script> <script>
import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters"; import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters";
// import MsTcpBasisParameters from "../../../definition/components/request/tcp/TcpBasisParameters"; import MsTcpFormatParameters from "../../../definition/components/request/tcp/TcpFormatParameters";
import MsTcpFormatParameters from "../../../definition/components/request/tcp/TcpFormatParameters";
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters"; import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm"; import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
import MsRequestResultTail from "../../../definition/components/response/RequestResultTail"; import MsRequestResultTail from "../../../definition/components/response/RequestResultTail";
@ -104,6 +108,7 @@ import {getUUID, getCurrentProjectID} from "@/common/js/utils";
import ApiBaseComponent from "../common/ApiBaseComponent"; import ApiBaseComponent from "../common/ApiBaseComponent";
import ApiResponseComponent from "./ApiResponseComponent"; import ApiResponseComponent from "./ApiResponseComponent";
import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo"; import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo";
import TemplateComponent from "@/business/components/track/plan/view/comonents/report/TemplateComponent/TemplateComponent";
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/); const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {}; const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {};
@ -133,6 +138,7 @@ export default {
envMap: Map envMap: Map
}, },
components: { components: {
TemplateComponent,
CustomizeReqInfo, CustomizeReqInfo,
ApiBaseComponent, ApiResponseComponent, ApiBaseComponent, ApiResponseComponent,
MsSqlBasisParameters, MsTcpFormatParameters, MsDubboBasisParameters, MsApiRequestForm, MsRequestResultTail, MsRun, MsSqlBasisParameters, MsTcpFormatParameters, MsDubboBasisParameters, MsApiRequestForm, MsRequestResultTail, MsRun,
@ -147,6 +153,7 @@ export default {
isShowInput: false, isShowInput: false,
showXpackCompnent: false, showXpackCompnent: false,
environment: {}, environment: {},
result: {},
} }
}, },
created() { created() {
@ -203,14 +210,14 @@ export default {
} }
return {}; return {};
}, },
isCompReadOnly(){ isCompReadOnly() {
if(this.request){ if (this.request) {
if(this.request.disabled){ if (this.request.disabled) {
return this.request.disabled; return this.request.disabled;
}else { } else {
return false; return false;
} }
}else { } else {
return false; return false;
} }
}, },
@ -462,6 +469,25 @@ export default {
} }
.ms-tag { .ms-tag {
margin-left: 20px; margin-left: 10px;
}
.ms-step-debug-code {
display: inline-block;
margin: 0 5px;
overflow-x: hidden;
padding-bottom: 0;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
width: 100px;
}
.ms-req-error {
color: #F56C6C;
}
.ms-req-success {
color: #67C23A;
} }
</style> </style>

View File

@ -16,169 +16,194 @@
:title="$t('api_test.automation.scenario_import')"> :title="$t('api_test.automation.scenario_import')">
<template v-slot:behindHeaderLeft> <template v-slot:behindHeaderLeft>
<el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='Deleted'" type="danger">{{$t('api_test.automation.reference_deleted')}}</el-tag> <el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='Deleted'" type="danger">{{ $t('api_test.automation.reference_deleted') }}</el-tag>
<el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='Copy'">{{ $t('commons.copy') }}</el-tag> <el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='Copy'">{{ $t('commons.copy') }}</el-tag>
<el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag> <el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
<span class="ms-tag">{{getProjectName(scenario.projectId)}}</span> <span class="ms-tag">{{ getProjectName(scenario.projectId) }}</span>
</template>
<template v-slot:debugStepCode>
<el-tooltip :content="getCode()" v-if="node.data.debug">
<span class="ms-step-debug-code" :class="node.data.code ==='error'?'ms-req-error':'ms-req-success'">
{{ getCode() }}
</span>
</el-tooltip>
</template> </template>
</api-base-component> </api-base-component>
</template> </template>
<script> <script>
import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters"; import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters";
import MsTcpBasisParameters from "../../../definition/components/request/tcp/TcpBasisParameters"; import MsTcpBasisParameters from "../../../definition/components/request/tcp/TcpBasisParameters";
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters"; import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm"; import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
import ApiBaseComponent from "../common/ApiBaseComponent"; import ApiBaseComponent from "../common/ApiBaseComponent";
import {getCurrentProjectID} from "@/common/js/utils"; import {getCurrentProjectID} from "@/common/js/utils";
export default { export default {
name: "ApiScenarioComponent", name: "ApiScenarioComponent",
props: { props: {
scenario: {}, scenario: {},
node: {}, node: {},
isMax: { isMax: {
type: Boolean, type: Boolean,
default: false, default: false,
},
showBtn: {
type: Boolean,
default: true,
},
draggable: {
type: Boolean,
default: false,
},
currentEnvironmentId: String,
projectList: Array
}, },
watch: {}, showBtn: {
created() { type: Boolean,
if (!this.scenario.projectId) { default: true,
this.scenario.projectId = getCurrentProjectID();
}
if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded) {
this.result = this.$get("/api/automation/getApiScenario/" + this.scenario.id, response => {
if (response.data) {
this.scenario.loaded = true;
let obj = {};
if (response.data.scenarioDefinition) {
obj = JSON.parse(response.data.scenarioDefinition);
this.scenario.hashTree = obj.hashTree;
}
this.scenario.projectId = response.data.projectId;
const pro = this.projectList.find(p => p.id === response.data.projectId);
if (!pro) {
this.scenario.projectId = getCurrentProjectID();
}
if (this.scenario.hashTree) {
this.setDisabled(this.scenario.hashTree, this.scenario.projectId);
}
//this.scenario.disabled = true;
this.scenario.name = response.data.name;
this.scenario.headers = obj.headers;
this.scenario.variables = obj.variables;
this.scenario.environmentMap = obj.environmentMap;
this.$emit('refReload');
} else {
this.scenario.referenced = "Deleted";
}
})
}
}, },
components: {ApiBaseComponent, MsSqlBasisParameters, MsTcpBasisParameters, MsDubboBasisParameters, MsApiRequestForm}, draggable: {
data() { type: Boolean,
return { default: false,
loading: false,
isShowInput: false,
}
}, },
computed: { currentEnvironmentId: String,
isDeletedOrRef() { projectList: Array
if (this.scenario.referenced != undefined && this.scenario.referenced === 'Deleted' || this.scenario.referenced === 'REF') { },
return true; watch: {},
} created() {
return false; if (!this.scenario.projectId) {
}, this.scenario.projectId = getCurrentProjectID();
projectId() { }
return getCurrentProjectID(); if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded) {
}, this.result = this.$get("/api/automation/getApiScenario/" + this.scenario.id, response => {
}, if (response.data) {
methods: { this.scenario.loaded = true;
remove() { let obj = {};
this.$emit('remove', this.scenario, this.node); if (response.data.scenarioDefinition) {
}, obj = JSON.parse(response.data.scenarioDefinition);
active() { this.scenario.hashTree = obj.hashTree;
if (this.node) {
this.node.expanded = !this.node.expanded;
} }
this.reload(); this.scenario.projectId = response.data.projectId;
}, const pro = this.projectList.find(p => p.id === response.data.projectId);
copyRow() { if (!pro) {
this.$emit('copyRow', this.scenario, this.node); this.scenario.projectId = getCurrentProjectID();
},
openScenario(data){
this.$emit('openScenario', data);
},
reload() {
this.loading = true
this.$nextTick(() => {
this.loading = false
})
},
recursive(arr, id) {
for (let i in arr) {
arr[i].disabled = true;
arr[i].projectId = this.calcProjectId(arr[i].projectId, id);
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
this.recursive(arr[i].hashTree, arr[i].projectId);
} }
} if (this.scenario.hashTree) {
}, this.setDisabled(this.scenario.hashTree, this.scenario.projectId);
setDisabled(scenarioDefinition, id) {
for (let i in scenarioDefinition) {
scenarioDefinition[i].disabled = true;
scenarioDefinition[i].projectId = this.calcProjectId(scenarioDefinition[i].projectId, id);
if (scenarioDefinition[i].hashTree != undefined && scenarioDefinition[i].hashTree.length > 0) {
this.recursive(scenarioDefinition[i].hashTree, scenarioDefinition[i].projectId);
} }
} //this.scenario.disabled = true;
}, this.scenario.name = response.data.name;
calcProjectId(projectId, parentId) { this.scenario.headers = obj.headers;
if (!projectId) { this.scenario.variables = obj.variables;
return parentId ? parentId : getCurrentProjectID(); this.scenario.environmentMap = obj.environmentMap;
this.$emit('refReload');
} else { } else {
const project = this.projectList.find(p => p.id === projectId); this.scenario.referenced = "Deleted";
if (project) {
return projectId;
}
return parentId ? parentId : getCurrentProjectID();
} }
}, })
getProjectName(id) { }
if (this.projectId !== id) { },
const project = this.projectList.find(p => p.id === id); components: {ApiBaseComponent, MsSqlBasisParameters, MsTcpBasisParameters, MsDubboBasisParameters, MsApiRequestForm},
return project ? project.name : ""; data() {
} return {
loading: false,
isShowInput: false,
}
},
computed: {
isDeletedOrRef() {
if (this.scenario.referenced != undefined && this.scenario.referenced === 'Deleted' || this.scenario.referenced === 'REF') {
return true;
} }
return false;
},
projectId() {
return getCurrentProjectID();
},
},
methods: {
getCode() {
if (this.node && this.node.data.debug) {
if (this.node.data.code && this.node.data.code === 'error') {
return 'error';
} else {
return 'success';
}
}
return '';
},
remove() {
this.$emit('remove', this.scenario, this.node);
},
active() {
if (this.node) {
this.node.expanded = !this.node.expanded;
}
this.reload();
},
copyRow() {
this.$emit('copyRow', this.scenario, this.node);
},
openScenario(data) {
this.$emit('openScenario', data);
},
reload() {
this.loading = true
this.$nextTick(() => {
this.loading = false
})
},
recursive(arr, id) {
for (let i in arr) {
arr[i].disabled = true;
arr[i].projectId = this.calcProjectId(arr[i].projectId, id);
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
this.recursive(arr[i].hashTree, arr[i].projectId);
}
}
},
setDisabled(scenarioDefinition, id) {
for (let i in scenarioDefinition) {
scenarioDefinition[i].disabled = true;
scenarioDefinition[i].projectId = this.calcProjectId(scenarioDefinition[i].projectId, id);
if (scenarioDefinition[i].hashTree != undefined && scenarioDefinition[i].hashTree.length > 0) {
this.recursive(scenarioDefinition[i].hashTree, scenarioDefinition[i].projectId);
}
}
},
calcProjectId(projectId, parentId) {
if (!projectId) {
return parentId ? parentId : getCurrentProjectID();
} else {
const project = this.projectList.find(p => p.id === projectId);
if (project) {
return projectId;
}
return parentId ? parentId : getCurrentProjectID();
}
},
getProjectName(id) {
if (this.projectId !== id) {
const project = this.projectList.find(p => p.id === id);
return project ? project.name : "";
}
} }
} }
}
</script> </script>
<style scoped> <style scoped>
/deep/ .el-card__body { /deep/ .el-card__body {
padding: 15px; padding: 15px;
} }
.icon.is-active { .icon.is-active {
transform: rotate(90deg); transform: rotate(90deg);
} }
.ms-tag { .ms-tag {
margin-left: 20px; margin-left: 0px;
} }
.ms-req-error {
color: #F56C6C;
}
.ms-req-success {
color: #67C23A;
}
</style> </style>

View File

@ -23,6 +23,13 @@
<el-input draggable size="mini" v-model="controller.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" class="ms-btn"/> <el-input draggable size="mini" v-model="controller.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" class="ms-btn"/>
</template> </template>
<template v-slot:debugStepCode>
<el-tooltip :content="getCode()" v-if="node.data.debug">
<span class="ms-step-debug-code" :class="node.data.code ==='error'?'ms-req-error':'ms-req-success'">
{{ getCode() }}
</span>
</el-tooltip>
</template>
</api-base-component> </api-base-component>
</template> </template>
@ -88,6 +95,16 @@
} }
}, },
methods: { methods: {
getCode() {
if (this.node && this.node.data.debug) {
if (this.node.data.code && this.node.data.code === 'error') {
return 'error';
} else {
return 'success';
}
}
return '';
},
remove() { remove() {
this.$emit('remove', this.controller, this.node); this.$emit('remove', this.controller, this.node);
}, },
@ -118,4 +135,12 @@
width: 15%; width: 15%;
margin-left: 5px; margin-left: 5px;
} }
.ms-req-error {
color: #F56C6C;
}
.ms-req-success {
color: #67C23A;
}
</style> </style>

View File

@ -69,6 +69,14 @@
<el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="3000" :step="1000"/> <el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="3000" :step="1000"/>
<span class="ms-span ms-radio">ms</span> <span class="ms-span ms-radio">ms</span>
</div> </div>
<template v-slot:debugStepCode>
<el-tooltip :content="getCode()" v-if="node.data.debug">
<span class="ms-step-debug-code" :class="node.data.code ==='error'?'ms-req-error':'ms-req-success'">
{{ getCode() }}
</span>
</el-tooltip>
</template>
</api-base-component> </api-base-component>
</div> </div>
@ -151,6 +159,16 @@
}; };
}, },
methods: { methods: {
getCode() {
if (this.node && this.node.data.debug) {
if (this.node.data.code && this.node.data.code === 'error') {
return 'error';
} else {
return 'success';
}
}
return '';
},
initResult() { initResult() {
if (this.controller) { if (this.controller) {
switch (this.controller.loopType) { switch (this.controller.loopType) {
@ -363,6 +381,13 @@
.icon.is-active { .icon.is-active {
transform: rotate(90deg); transform: rotate(90deg);
} }
.ms-req-error {
color: #F56C6C;
}
.ms-req-success {
color: #67C23A;
}
/deep/ .el-radio { /deep/ .el-radio {
margin-right: 5px; margin-right: 5px;

View File

@ -17,6 +17,10 @@
<el-tooltip :content="$t('api_test.scenario.enable')" placement="top" effect="light" v-else> <el-tooltip :content="$t('api_test.scenario.enable')" placement="top" effect="light" v-else>
<font-awesome-icon class="ms-open-btn" :icon="['fas', 'toggle-on']" @click="disableAll"/> <font-awesome-icon class="ms-open-btn" :icon="['fas', 'toggle-on']" @click="disableAll"/>
</el-tooltip> </el-tooltip>
<span class="ms-debug-result" v-if="debug">
{{ reqTotalTime }} ms 请求 {{ reqTotal }} 成功 {{ reqSuccess }} 失败 {{ reqError }}
</span>
<el-tree node-key="resourceId" <el-tree node-key="resourceId"
:props="props" :props="props"
:data="scenarioDefinition" :data="scenarioDefinition"
@ -175,9 +179,15 @@ export default {
moduleOptions: Array, moduleOptions: Array,
currentScenario: {}, currentScenario: {},
type: String, type: String,
debug: Boolean,
reloadDebug: String,
stepReEnable: Boolean, stepReEnable: Boolean,
scenarioDefinition: Array, scenarioDefinition: Array,
envMap: Map, envMap: Map,
reqTotal: Number,
reqSuccess: Number,
reqError: Number,
reqTotalTime: Number,
}, },
components: { components: {
MsVariableList, MsVariableList,
@ -242,6 +252,7 @@ export default {
debugResult: new Map, debugResult: new Map,
expandedStatus: false, expandedStatus: false,
stepEnable: true, stepEnable: true,
debugLoading: false,
} }
}, },
created() { created() {
@ -255,6 +266,9 @@ export default {
watch: { watch: {
envMap() { envMap() {
this.projectEnvMap = this.envMap; this.projectEnvMap = this.envMap;
},
reloadDebug() {
this.reload();
} }
}, },
directives: {OutsideClick}, directives: {OutsideClick},
@ -1198,4 +1212,10 @@ export default {
.ms-open-btn-left { .ms-open-btn-left {
margin-left: 30px; margin-left: 30px;
} }
.ms-debug-result {
float: right;
margin-right: 30px;
margin-top: 3px;
}
</style> </style>

View File

@ -5,15 +5,15 @@
<el-row class="ms-header-margin"> <el-row class="ms-header-margin">
<el-col :span="8"> <el-col :span="8">
<el-tooltip placement="top" :content="currentScenario.name"> <el-tooltip placement="top" :content="currentScenario.name">
<span class="ms-scenario-name">{{currentScenario.name}}</span> <span class="ms-scenario-name">{{ currentScenario.name }}</span>
</el-tooltip> </el-tooltip>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
{{$t('api_test.automation.step_total')}}{{scenarioDefinition.length}} {{ $t('api_test.automation.step_total') }}{{ scenarioDefinition.length }}
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-link class="head" @click="showScenarioParameters">{{$t('api_test.automation.scenario_total')}}</el-link> <el-link class="head" @click="showScenarioParameters">{{ $t('api_test.automation.scenario_total') }}</el-link>
{{varSize }} {{ varSize }}
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
@ -25,10 +25,13 @@
@showPopover="showPopover" :project-list="projectList" ref="envPopover" class="ms-right" @showPopover="showPopover" :project-list="projectList" ref="envPopover" class="ms-right"
:result="envResult"/> :result="envResult"/>
<el-button :disabled="scenarioDefinition.length < 1" size="mini" type="primary" v-prevent-re-click <el-dropdown split-button type="primary" @click="runDebug" style="margin-right: 10px" size="mini" @command="handleCommand" v-if="!debug">
@click="runDebug">{{ $t('api_test.request.debug') }} {{ $t('api_test.request.debug') }}
</el-button> <el-dropdown-menu slot="dropdown">
<el-dropdown-item>{{ $t('test_track.case.steps') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button icon="el-icon-loading" size="mini" type="primary" :disabled="debug" v-else>执行中</el-button>
<font-awesome-icon class="ms-alt-ico" :icon="['fa', 'compress-alt']" size="lg" @click="unFullScreen"/> <font-awesome-icon class="ms-alt-ico" :icon="['fa', 'compress-alt']" size="lg" @click="unFullScreen"/>
<!-- <i class="el-icon-close alt-ico-close" @click="close"/>--> <!-- <i class="el-icon-close alt-ico-close" @click="close"/>-->
</div> </div>
@ -38,185 +41,206 @@
<script> <script>
import {exportPdf, getCurrentProjectID} from "@/common/js/utils"; import {exportPdf, getCurrentProjectID} from "@/common/js/utils";
import html2canvas from 'html2canvas'; import html2canvas from 'html2canvas';
import EnvPopover from "../../scenario/EnvPopover"; import EnvPopover from "../../scenario/EnvPopover";
export default { export default {
name: "ScenarioHeader", name: "ScenarioHeader",
components: {EnvPopover}, components: {EnvPopover},
props: { props: {
currentScenario: {}, scenarioDefinition: Array, enableCookieShare: Boolean, onSampleError: Boolean, currentScenario: {}, scenarioDefinition: Array, enableCookieShare: Boolean, onSampleError: Boolean,
projectEnvMap: Map, projectEnvMap: Map,
projectIds: Set, projectIds: Set,
projectList: Array, projectList: Array,
isFullUrl: Boolean isFullUrl: Boolean,
execDebug: String,
},
data() {
return {
envMap: new Map,
loading: false,
varSize: 0,
cookieShare: false,
sampleError: true,
envResult: {
loading: false
},
debugLoading: false,
reqTotal: 0,
reqSuccess: 0,
reqError: 0,
reqTotalTime: 0,
debug: false,
}
},
computed: {
projectId() {
return getCurrentProjectID();
}, },
data() { },
return { watch:{
envMap: new Map, execDebug(){
loading: false, this.debug = false;
varSize: 0, }
cookieShare: false, },
sampleError: true, mounted() {
envResult: { this.envMap = this.projectEnvMap;
loading: false this.getVariableSize();
} this.cookieShare = this.enableCookieShare;
this.sampleError = this.onSampleError;
},
methods: {
handleExport() {
let name = this.$t('commons.report_statistics.test_case_analysis');
this.$nextTick(function () {
setTimeout(() => {
html2canvas(document.getElementById('reportAnalysis'), {
scale: 2
}).then(function (canvas) {
exportPdf(name, [canvas]);
});
}, 1000);
});
},
showAll() {
this.$emit('showAllBtn');
},
close() {
this.$emit('closePage', this.currentScenario.name);
},
unFullScreen() {
this.$emit('unFullScreen');
},
runDebug() {
this.debug = true;
this.debugLoading = true;
this.$emit('runDebug');
},
handleCommand() {
this.debug = false;
this.debugLoading = false;
this.$emit('handleCommand');
},
setCookieShare() {
this.$emit('setCookieShare', this.cookieShare);
},
setOnSampleError() {
this.$emit('setSampleError', this.sampleError);
},
showScenarioParameters() {
this.$emit('showScenarioParameters');
},
getVariableSize() {
let size = 0;
if (this.currentScenario.variables) {
size += this.currentScenario.variables.length;
} }
}, if (this.currentScenario.headers && this.currentScenario.headers.length > 1) {
computed: { size += this.currentScenario.headers.length - 1;
projectId() {
return getCurrentProjectID();
} }
this.varSize = size;
this.reload();
}, },
mounted() { reload() {
this.envMap = this.projectEnvMap; this.loading = true
this.getVariableSize(); this.$nextTick(() => {
this.cookieShare = this.enableCookieShare; this.loading = false
this.sampleError = this.onSampleError; })
}, },
methods: { setProjectEnvMap(projectEnvMap) {
handleExport() { this.$emit('setProjectEnvMap', projectEnvMap);
let name = this.$t('commons.report_statistics.test_case_analysis'); this.envMap = projectEnvMap;
this.$nextTick(function () { },
setTimeout(() => { showPopover() {
html2canvas(document.getElementById('reportAnalysis'), { let definition = JSON.parse(JSON.stringify(this.currentScenario));
scale: 2 definition.hashTree = this.scenarioDefinition;
}).then(function (canvas) { this.envResult.loading = true;
exportPdf(name, [canvas]); this.getEnv(JSON.stringify(definition)).then(() => {
}); this.$refs.envPopover.openEnvSelect();
}, 1000); this.envResult.loading = false;
}); })
}, },
showAll() { getEnv(definition) {
this.$emit('showAllBtn'); return new Promise((resolve) => {
}, this.$post("/api/automation/getApiScenarioEnv", {definition: definition}, res => {
close() { if (res.data) {
this.$emit('closePage', this.currentScenario.name); res.data.projectIds.push(this.projectId);
}, this.$emit("update:projectIds", new Set(res.data.projectIds));
unFullScreen() { this.$emit("update:isFullUrl", res.data.fullUrl);
this.$emit('unFullScreen'); }
}, resolve();
runDebug() {
this.$emit('runDebug');
},
setCookieShare() {
this.$emit('setCookieShare', this.cookieShare);
},
setOnSampleError() {
this.$emit('setSampleError', this.sampleError);
},
showScenarioParameters() {
this.$emit('showScenarioParameters');
},
getVariableSize() {
let size = 0;
if (this.currentScenario.variables) {
size += this.currentScenario.variables.length;
}
if (this.currentScenario.headers && this.currentScenario.headers.length > 1) {
size += this.currentScenario.headers.length - 1;
}
this.varSize = size;
this.reload();
},
reload() {
this.loading = true
this.$nextTick(() => {
this.loading = false
}) })
}, });
setProjectEnvMap(projectEnvMap) {
this.$emit('setProjectEnvMap', projectEnvMap);
this.envMap = projectEnvMap;
},
showPopover() {
let definition = JSON.parse(JSON.stringify(this.currentScenario));
definition.hashTree = this.scenarioDefinition;
this.envResult.loading = true;
this.getEnv(JSON.stringify(definition)).then(() => {
this.$refs.envPopover.openEnvSelect();
this.envResult.loading = false;
})
},
getEnv(definition) {
return new Promise((resolve) => {
this.$post("/api/automation/getApiScenarioEnv", {definition: definition}, res => {
if (res.data) {
res.data.projectIds.push(this.projectId);
this.$emit("update:projectIds", new Set(res.data.projectIds));
this.$emit("update:isFullUrl", res.data.fullUrl);
}
resolve();
})
});
},
}, },
} },
}
</script> </script>
<style scoped> <style scoped>
.ms-header { .ms-header {
border-bottom: 1px solid #E6E6E6; border-bottom: 1px solid #E6E6E6;
height: 50px; height: 50px;
background-color: #FFF; background-color: #FFF;
} }
.ms-div { .ms-div {
float: left; float: left;
width: 60%; width: 60%;
margin-left: 20px; margin-left: 20px;
margin-top: 12px; margin-top: 12px;
} }
.ms-header-right { .ms-header-right {
float: right; float: right;
width: 500px; width: 540px;
margin-top: 4px; margin-top: 4px;
z-index: 1; z-index: 1;
} }
.alt-ico-close { .alt-ico-close {
font-size: 18px; font-size: 18px;
margin: 10px 10px 10px; margin: 10px 10px 10px;
} }
.alt-ico-close:hover { .alt-ico-close:hover {
color: black; color: black;
cursor: pointer; cursor: pointer;
} }
.ms-alt-ico { .ms-alt-ico {
color: #8c939d; color: #8c939d;
font-size: 16px; font-size: 16px;
margin: 10px 30px 0px; margin: 10px 30px 0px;
} }
.ms-alt-ico:hover { .ms-alt-ico:hover {
color: black; color: black;
cursor: pointer; cursor: pointer;
} }
.ms-header-margin { .ms-header-margin {
margin-top: 3px; margin-top: 3px;
} }
.ms-right { .ms-right {
margin-right: 40px; margin-right: 40px;
} }
.head {
border-bottom: 1px solid #303133;
color: #303133;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
font-size: 13px;
}
.ms-scenario-name {
display: inline-block;
margin: 0 5px;
overflow-x: hidden;
padding-bottom: 0;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
width: 200px;
}
.head {
border-bottom: 1px solid #303133;
color: #303133;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
font-size: 13px;
}
.ms-scenario-name {
display: inline-block;
margin: 0 5px;
overflow-x: hidden;
padding-bottom: 0;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
width: 200px;
}
</style> </style>

View File

@ -0,0 +1,182 @@
import {ELEMENT_TYPE} from "@/business/components/api/automation/scenario/Setting";
import {Assertions, ConstantTimer, Extract, IfController, JSR223Processor, LoopController, TransactionController} from "@/business/components/api/definition/model/ApiTestModel";
export function buttons() {
let buttons = [
{
title: this.$t('api_test.definition.request.extract_param'),
show: this.showButton("Extract"),
titleColor: "#015478",
titleBgColor: "#E6EEF2",
icon: "colorize",
click: () => {
this.addComponent('Extract')
}
},
{
title: this.$t('api_test.definition.request.post_script'),
show: this.showButton("JSR223PostProcessor"),
titleColor: "#783887",
titleBgColor: "#F2ECF3",
icon: "skip_next",
click: () => {
this.addComponent('JSR223PostProcessor')
}
},
{
title: this.$t('api_test.definition.request.pre_script'),
show: this.showButton("JSR223PreProcessor"),
titleColor: "#B8741A",
titleBgColor: "#F9F1EA",
icon: "skip_previous",
click: () => {
this.addComponent('JSR223PreProcessor')
}
},
{
title: this.$t('api_test.automation.customize_script'),
show: this.showButton("JSR223Processor"),
titleColor: "#7B4D12",
titleBgColor: "#F1EEE9",
icon: "code",
click: () => {
this.addComponent('JSR223Processor')
}
},
{
title: this.$t('api_test.automation.if_controller'),
show: this.showButton("IfController"),
titleColor: "#E6A23C",
titleBgColor: "#FCF6EE",
icon: "alt_route",
click: () => {
this.addComponent('IfController')
}
},
{
title: this.$t('api_test.automation.loop_controller'),
show: this.showButton("LoopController"),
titleColor: "#02A7F0",
titleBgColor: "#F4F4F5",
icon: "next_plan",
click: () => {
this.addComponent('LoopController')
}
},
{
title: this.$t('api_test.automation.transcation_controller'),
show: this.showButton("TransactionController"),
titleColor: "#6D317C",
titleBgColor: "#F4F4F5",
icon: "alt_route",
click: () => {
this.addComponent('TransactionController')
}
},
{
title: this.$t('api_test.automation.wait_controller'),
show: this.showButton("ConstantTimer"),
titleColor: "#67C23A",
titleBgColor: "#F2F9EE",
icon: "access_time",
click: () => {
this.addComponent('ConstantTimer')
}
},
{
title: this.$t('api_test.definition.request.assertions_rule'),
show: this.showButton("Assertions"),
titleColor: "#A30014",
titleBgColor: "#F7E6E9",
icon: "next_plan",
click: () => {
this.addComponent('Assertions')
}
},
{
title: this.$t('api_test.automation.customize_req'),
show: this.showButton("CustomizeReq"),
titleColor: "#008080",
titleBgColor: "#EBF2F2",
icon: "tune",
click: () => {
this.addComponent('CustomizeReq')
}
},
{
title: this.$t('api_test.automation.scenario_import'),
show: this.showButton("scenario"),
titleColor: "#606266",
titleBgColor: "#F4F4F5",
icon: "movie",
click: () => {
this.addComponent('scenario')
}
},
{
title: this.$t('api_test.automation.api_list_import'),
show: this.showButton("HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler"),
titleColor: "#F56C6C",
titleBgColor: "#FCF1F1",
icon: "api",
click: this.apiListImport
}
];
return buttons.filter(btn => btn.show);
}
export function setComponent(type, _this) {
switch (type) {
case ELEMENT_TYPE.IfController:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new IfController()) :
_this.scenarioDefinition.push(new IfController());
break;
case ELEMENT_TYPE.ConstantTimer:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new ConstantTimer()) :
_this.scenarioDefinition.push(new ConstantTimer());
break;
case ELEMENT_TYPE.JSR223Processor:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new JSR223Processor()) :
_this.scenarioDefinition.push(new JSR223Processor());
break;
case ELEMENT_TYPE.JSR223PreProcessor:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new JSR223Processor({type: "JSR223PreProcessor"})) :
_this.scenarioDefinition.push(new JSR223Processor({type: "JSR223PreProcessor"}));
break;
case ELEMENT_TYPE.JSR223PostProcessor:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new JSR223Processor({type: "JSR223PostProcessor"})) :
_this.scenarioDefinition.push(new JSR223Processor({type: "JSR223PostProcessor"}));
break;
case ELEMENT_TYPE.Assertions:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new Assertions()) :
_this.scenarioDefinition.push(new Assertions());
break;
case ELEMENT_TYPE.Extract:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new Extract()) :
_this.scenarioDefinition.push(new Extract());
break;
case ELEMENT_TYPE.CustomizeReq:
_this.customizeRequest = {protocol: "HTTP", type: "API", hashTree: [], referenced: 'Created', active: false};
_this.customizeVisible = true;
break;
case ELEMENT_TYPE.LoopController:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new LoopController()) :
_this.scenarioDefinition.push(new LoopController());
break;
case ELEMENT_TYPE.TransactionController:
_this.selectedTreeNode !== undefined ? _this.selectedTreeNode.hashTree.push(new TransactionController()) :
_this.scenarioDefinition.push(new TransactionController());
break;
case ELEMENT_TYPE.scenario:
_this.isBtnHide = true;
_this.$refs.scenarioRelevance.open();
break;
default:
_this.$refs.apiImport.open();
break;
}
if (_this.selectedNode) {
_this.selectedNode.expanded = true;
}
_this.sort();
}