refactor: groovy请求函数模版

This commit is contained in:
shiziyuan9527 2021-09-14 18:27:58 +08:00 committed by 刘瑞斌
parent 05789ad717
commit 069c747ab8
6 changed files with 343 additions and 15 deletions

View File

@ -29,6 +29,7 @@
:current-module="currentModule"
:is-read-only="isReadOnly"
:moduleOptions="data"
:options="options"
@exportAPI="exportAPI"
@saveAsEdit="saveAsEdit"
@refreshTable="$emit('refreshTable')"
@ -87,6 +88,12 @@
relevanceProjectId: String,
reviewId: String,
pageSource:String,
options: {
type: Array,
default() {
return OPTIONS;
}
}
},
computed: {
isPlanModel() {

View File

@ -46,7 +46,6 @@ export default {
components: {MsSearchBar, TemplateComponent, ModuleTrashButton, ApiImport, MsAddBasisApi},
data() {
return {
options: OPTIONS,
operators: [
{
label: this.$t('api_test.definition.request.title'),
@ -123,6 +122,12 @@ export default {
return false;
}
},
options: {
type: Array,
default() {
return OPTIONS;
}
}
},
computed: {
projectId() {

View File

@ -0,0 +1,201 @@
<template>
<test-case-relevance-base
@setProject="setProject"
@save="save"
:plan-id="planId"
ref="baseRelevance">
<template v-slot:aside>
<ms-api-module
:options="options"
:relevance-project-id="projectId"
@nodeSelectEvent="nodeChange"
@protocolChange="handleProtocolChange"
@refreshTable="refresh"
@setModuleOptions="setModuleOptions"
:is-read-only="true"
ref="nodeTree"/>
</template>
<relevance-api-list
v-if="isApiListEnable"
:current-protocol="currentProtocol"
:select-node-ids="selectNodeIds"
:is-api-list-enable="isApiListEnable"
:project-id="projectId"
:is-test-plan="true"
:plan-id="planId"
@isApiListEnableChange="isApiListEnableChange"
ref="apiList"/>
<relevance-case-list
v-if="!isApiListEnable"
:current-protocol="currentProtocol"
:select-node-ids="selectNodeIds"
:is-api-list-enable="isApiListEnable"
:project-id="projectId"
:is-test-plan="true"
:plan-id="planId"
@isApiListEnableChange="isApiListEnableChange"
ref="apiCaseList"/>
</test-case-relevance-base>
</template>
<script>
import RelevanceCaseList from "@/business/components/api/automation/scenario/api/RelevanceCaseList";
import RelevanceApiList from "@/business/components/api/automation/scenario/api/RelevanceApiList";
import MsApiModule from "@/business/components/api/definition/components/module/ApiModule";
import TestCaseRelevanceBase from "@/business/components/track/plan/view/comonents/base/TestCaseRelevanceBase";
import {parseEnvironment} from "@/business/components/api/test/model/EnvironmentModel";
export default {
name: "ApiFuncRelevance",
components: {
RelevanceCaseList,
RelevanceApiList,
MsApiModule,
TestCaseRelevanceBase,
},
data() {
return {
showCasePage: true,
currentProtocol: null,
currentModule: null,
selectNodeIds: [],
moduleOptions: {},
trashEnable: false,
isApiListEnable: true,
condition: {},
currentRow: {},
projectId: "",
options: [{value: 'HTTP', name: 'HTTP'}]
};
},
props: {
planId: {
type: String
}
},
watch: {
planId() {
this.condition.planId = this.planId;
},
},
methods: {
open() {
this.init();
this.$refs.baseRelevance.open();
if (this.$refs.apiList) {
this.$refs.apiList.clear();
}
if (this.$refs.apiCaseList) {
this.$refs.apiCaseList.clear();
}
},
close() {
this.$refs.baseRelevance.close();
},
init() {
if (this.$refs.apiList) {
this.$refs.apiList.initTable();
}
if (this.$refs.apiCaseList) {
this.$refs.apiCaseList.initTable();
}
if (this.$refs.nodeTree) {
this.$refs.nodeTree.list();
}
},
setProject(projectId) {
//
if (this.$refs.apiList) {
this.$refs.apiList.clearEnvAndSelect();
}
if (this.$refs.apiCaseList) {
this.$refs.apiCaseList.clearEnvAndSelect();
}
this.projectId = projectId;
},
isApiListEnableChange(data) {
this.isApiListEnable = data;
},
refresh(data) {
if (this.isApiListEnable) {
this.$refs.apiList.initTable(data);
} else {
this.$refs.apiCaseList.initTable(data);
}
},
nodeChange(node, nodeIds, pNodes) {
this.selectNodeIds = nodeIds;
},
handleProtocolChange(protocol) {
this.currentProtocol = protocol;
},
setModuleOptions(data) {
this.moduleOptions = data;
},
save() {
let url = '';
let environmentId = undefined;
let selectIds = [];
if (this.isApiListEnable) {
//
let params = this.$refs.apiList.getConditions();
this.result = this.$post("/api/definition/list/batch", params, (response) => {
let apis = response.data;
url = '/api/definition/relevance';
environmentId = this.$refs.apiList.environmentId;
if (!environmentId) {
this.$warning(this.$t('api_test.environment.select_environment'));
return;
}
this.$get('/api/environment/get/' + environmentId, response => {
let environment = response.data;
parseEnvironment(environment);
this.$emit("save", apis, environment, "API");
});
});
} else {
let params = this.$refs.apiCaseList.getConditions();
this.result = this.$post("/api/testcase/get/caseBLOBs/request", params, (response) => {
let apiCases = response.data;
url = '/api/testcase/relevance';
environmentId = this.$refs.apiCaseList.environmentId;
if (!environmentId) {
this.$warning(this.$t('api_test.environment.select_environment'));
return;
}
this.$get('/api/environment/get/' + environmentId, response => {
let environment = response.data;
parseEnvironment(environment);
this.$emit("save", apiCases, environment, "CASE");
});
});
}
},
}
}
</script>
<style scoped>
/deep/ .select-menu {
margin-bottom: 15px;
}
/deep/ .environment-select {
float: right;
margin-right: 10px;
}
</style>

View File

@ -2,7 +2,8 @@
<el-dialog :close-on-click-modal="false" :title="dialogTitle" :visible.sync="visible" :destroy-on-close="true"
@close="close" width="65%" top="5vh" v-loading="result.loading">
<div style="height: 61vh; overflow-y: auto; overflow-x: hidden">
<el-form :model="form" label-position="right" label-width="80px" size="small" :rules="rules" v-if="isFormAlive">
<el-form :model="form" label-position="right" label-width="80px" size="small" :rules="rules" v-if="isFormAlive"
ref="form">
<el-row type="flex" :gutter="20">
<el-col>
<el-form-item :label="$t('commons.name')" prop="name">
@ -45,7 +46,8 @@
</el-tab-pane>
<el-tab-pane :label="'执行结果'" name="result">
<div v-loading="runResult.loading">
<ms-code-edit :mode="'text'" :data.sync="console" v-if="isResultAlive" height="330px" ref="funcResult"/>
<ms-code-edit :mode="'text'" :data.sync="console" v-if="isResultAlive" height="330px"
ref="funcResult"/>
</div>
</el-tab-pane>
</el-tabs>
@ -55,7 +57,9 @@
<el-col :span="4" class="script-index">
<div style="margin-top: -25px; margin-left: 10px;">
<div style="margin-bottom: 10px;">
<el-button type="primary" size="mini" style="width: 70px;" @click="handleTest" :disabled="runResult.loading">测试</el-button>
<el-button type="primary" size="mini" style="width: 70px;" @click="handleTest"
:disabled="runResult.loading">测试
</el-button>
</div>
<ms-dropdown :default-command="form.type" :commands="languages" @command="languageChange"/>
<div class="template-title">{{ $t('api_test.request.processor.code_template') }}</div>
@ -76,6 +80,8 @@
<!-- 执行组件 -->
<function-run :report-id="reportId" :run-data="runData" @runRefresh="runRefresh" @errorRefresh="errorRefresh"/>
<custom-function-relate ref="customFunctionRelate" @addCustomFuncScript="addCustomFuncScript"/>
<!--接口列表-->
<api-func-relevance @save="apiSave" @close="apiClose" ref="apiFuncRelevance"/>
</div>
<template v-slot:footer>
<el-button @click="close" size="medium">{{ $t('commons.cancel') }}</el-button>
@ -91,12 +97,13 @@ import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag
import FunctionParams from "@/business/components/settings/project/function/FunctionParams";
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
import MsDropdown from "@/business/components/common/components/MsDropdown";
import {FUNC_TEMPLATE} from "@/business/components/settings/project/function/custom-function";
import {FUNC_TEMPLATE, getCodeTemplate} from "@/business/components/settings/project/function/custom-function";
import MsRun from "@/business/components/api/automation/scenario/DebugRun";
import {getCurrentProjectID, getUUID} from "@/common/js/utils";
import {JSR223Processor} from "@/business/components/api/definition/model/ApiTestModel";
import FunctionRun from "@/business/components/settings/project/function/FunctionRun";
import CustomFunctionRelate from "@/business/components/settings/project/function/CustomFunctionRelate";
import ApiFuncRelevance from "@/business/components/settings/project/function/ApiFuncRelevance";
export default {
name: "EditFunction",
@ -107,7 +114,8 @@ export default {
FunctionParams,
MsInputTag,
MsDropdown,
MsRun
MsRun,
ApiFuncRelevance
},
props: {},
data() {
@ -215,6 +223,16 @@ export default {
title: "插入自定义函数",
command: "custom_function",
index: "custom_function"
},
{
title: "从API定义导入",
command: "api_definition",
index: "api_definition"
},
{
title: "新API测试[JSON]",
command: "new_api",
index: "new_api"
}
],
@ -280,6 +298,8 @@ export default {
doFuncLink(funcLink) {
if (funcLink.command === 'custom_function') {
this.$refs.customFunctionRelate.open(this.form.type);
} else if (funcLink.command === 'api_definition') {
this.$refs.apiFuncRelevance.open();
}
},
reload() {
@ -300,11 +320,17 @@ export default {
let param = Object.assign({}, this.form);
param.params = JSON.stringify(this.form.params);
param.tags = JSON.stringify(this.form.tags);
if (this.form.id) {
this.update(param);
} else {
this.create(param);
}
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id) {
this.update(param);
} else {
this.create(param);
}
} else {
return false;
}
})
},
create(obj) {
this.result = this.$post("/custom/func/save", obj, res => {
@ -350,7 +376,52 @@ export default {
addCustomFuncScript(script) {
this.form.script = this.form.script + '\n\n' + script;
this.reloadCodeEdit();
}
},
apiSave(data, env, type) {
// dataenv:
let condition = env.config.httpConfig.conditions || [];
let requestUrl = "";
let requestHeaders = new Map;
let requestMethod = "";
let requestBody = "";
if (condition && condition.length > 0) {
//
let protocol = condition[0].protocol ? condition[0].protocol : "http";
requestUrl = protocol + "://" + condition[0].socket;
}
// todo
if (data.length > 0) {
let request = JSON.parse(data[0].request);
requestUrl = requestUrl + request.path;
requestMethod = request.method;
let headers = request.headers;
if (headers && headers.length > 0) {
headers.forEach(header => {
if (header.name) {
requestHeaders.set(header.name, header.value);
}
})
}
let body = request.body;
if (body.json) {
requestBody = body.raw;
}
}
let param = {requestUrl, requestHeaders, requestMethod, requestBody};
let code = getCodeTemplate(this.form.type, param);
if (code) {
let codeStr = this.form.script + "\n\n" + code;
this.form.script = this.form.script ? codeStr : code;
this.reloadCodeEdit();
} else {
//todo
this.$warning("无对应语言模版");
}
this.$refs.apiFuncRelevance.close();
},
apiClose() {
},
}
}
</script>

View File

@ -1,7 +1,51 @@
export const FUNC_TEMPLATE = {
beanshell: "public static void test() {\n\n\n}",
groovy: "public static void test() {\n\n\n}",
beanshell: "public void test() {\n\n\n}",
groovy: "def test() {\n\n\n}",
python: "def test():\n",
nashornScript: "function test() {\n\n\n}",
rhinoScript: "function test() {\n\n\n}"
}
export function getCodeTemplate(language, requestObj) {
// 拼装代码模版的请求参数
if (language === "groovy") {
return groovyCode(requestObj);
} else {
return "";
}
}
function groovyCode(obj) {
let {requestHeaders, requestBody, requestUrl, requestMethod} = obj;
let headers = "", body = JSON.stringify(requestBody);
for (let [k, v] of requestHeaders) {
headers += `['${k}':'${v}']`;
}
return `
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
def http_post() {
def headers = ${headers} // 请求headers 例:['Content-type':'application/json']
// json数据
def data = ${body}
def conn = new URL("${requestUrl}").openConnection()
conn.setRequestMethod("${requestMethod}")
if (data) {
headers.each {
k,v -> conn.setRequestProperty(k, v);
}
// 输出请求参数
log.info(data)
conn.doOutput = true
def writer = new OutputStreamWriter(conn.outputStream)
writer.write(data)
writer.flush()
writer.close()
}
log.info(conn.content.text)
}
http_post()
`;
}

View File

@ -22,7 +22,7 @@
</el-menu>
<el-drawer :visible.sync="taskVisible" :destroy-on-close="true" direction="rtl"
:withHeader="true" :modal="false" :title="$t('commons.task_center')" :size="size"
:withHeader="true" :modal="false" :title="$t('commons.task_center')" :size="size.toString()"
custom-class="ms-drawer-task">
<el-card style="float: left;width: 800px" v-if="size > 550 ">