feat(接口自动化): 统一项目获取

This commit is contained in:
fit2-zhao 2020-12-10 13:45:10 +08:00
parent bc49f69ede
commit 7f98702691
20 changed files with 396 additions and 448 deletions

View File

@ -118,8 +118,7 @@ public abstract class MsTestElement {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ApiDefinitionWithBLOBs apiDefinition = apiDefinitionService.getBLOBs(this.getId());
element = mapper.readValue(apiDefinition.getRequest(), new TypeReference<MsTestElement>() {
});
element = mapper.readValue(apiDefinition.getRequest(), new TypeReference<MsTestElement>() {});
hashTree.add(element);
} catch (Exception ex) {
ex.printStackTrace();

View File

@ -243,11 +243,9 @@ public class ApiAutomationService {
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
// 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
new TypeReference<LinkedList<MsTestElement>>() {
});
new TypeReference<LinkedList<MsTestElement>>() {});
LinkedList<KeyValue> variables = mapper.readValue(element.getString("variables"),
new TypeReference<LinkedList<KeyValue>>() {
});
new TypeReference<LinkedList<KeyValue>>() {});
scenario.setHashTree(elements);
scenario.setVariables(variables);
LinkedList<MsTestElement> scenarios = new LinkedList<>();
@ -285,8 +283,6 @@ public class ApiAutomationService {
ParameterConfig config = new ParameterConfig();
config.setConfig(envConfig);
HashTree hashTree = request.getTestElement().generateHashTree(config);
request.getTestElement().getJmx(hashTree);
// 调用执行方法
jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name());
createAPIReportResult(request.getId(), ReportTriggerMode.MANUAL.name());

View File

@ -1,14 +1,13 @@
<template>
<ms-container>
<ms-aside-container>
<ms-api-scenario-module @selectModule="selectModule" @getApiModuleTree="initTree" @changeProject="changeProject"
<ms-api-scenario-module @selectModule="selectModule" @getApiModuleTree="initTree"
@refresh="refresh" @saveAsEdit="editScenario"/>
</ms-aside-container>
<ms-main-container>
<el-tabs v-model="activeName" @tab-click="addTab" @tab-remove="removeTab">
<el-tab-pane name="default" :label="$t('api_test.automation.scenario_test')">
<ms-api-scenario-list
:current-project="currentProject"
:current-module="currentModule"
@edit="editScenario"
ref="apiScenarioList"/>
@ -21,7 +20,7 @@
:name="item.name"
closable>
<div class="ms-api-scenario-div">
<ms-edit-api-scenario :current-project="currentProject" :currentScenario="item.currentScenario" :moduleOptions="moduleOptions"/>
<ms-edit-api-scenario :currentScenario="item.currentScenario" :moduleOptions="moduleOptions"/>
</div>
</el-tab-pane>
@ -53,7 +52,6 @@
return {
isHide: true,
activeName: 'default',
currentProject: null,
currentModule: null,
moduleOptions: {},
tabs: [],
@ -102,9 +100,6 @@
initTree(data) {
this.moduleOptions = data;
},
changeProject(data) {
this.currentProject = data;
},
refresh(data) {
this.$refs.apiScenarioList.search(data);
},

View File

@ -58,9 +58,8 @@
<script>
import {WORKSPACE_ID} from '@/common/js/constants';
import {getCurrentUser, getUUID} from "@/common/js/utils";
import {getCurrentUser, getUUID,getCurrentProjectID} from "@/common/js/utils";
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
export default {
name: "MsAddBasisScenario",
components: {MsDialogFooter},
@ -70,7 +69,6 @@ export default {
scenarioForm: {},
visible: false,
currentModule: {},
projectId: "",
userOptions: [],
rule: {
name: [
@ -107,7 +105,7 @@ export default {
})
},
setParameter() {
this.scenarioForm.projectId = this.projectId;
this.scenarioForm.projectId = getCurrentProjectID();
this.scenarioForm.id = getUUID().substring(0, 8);
this.scenarioForm.protocol = this.currentProtocol;
if (this.currentModule != null) {
@ -121,10 +119,9 @@ export default {
this.userOptions = response.data;
});
},
open(currentModule, projectId) {
open(currentModule) {
this.scenarioForm = {principal: getCurrentUser().id};
this.currentModule = currentModule;
this.projectId = projectId;
this.getMaintainerOptions();
this.visible = true;
}

View File

@ -38,10 +38,9 @@
<script>
import {WORKSPACE_ID} from '@/common/js/constants';
import {getCurrentUser, getUUID} from "@/common/js/utils";
import {getCurrentUser, getUUID,getCurrentProjectID} from "@/common/js/utils";
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
import MsTablePagination from "../../../common/pagination/TablePagination";
export default {
name: "MsAddTag",
components: {MsDialogFooter,MsTablePagination},
@ -94,8 +93,8 @@
setParameter() {
this.tagForm.projectId = this.projectId;
},
open(projectId) {
this.projectId = projectId;
open() {
this.projectId = getCurrentProjectID();
this.visible = true;
this.initTable();
},

View File

@ -30,9 +30,9 @@
</div>
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
<ms-api-request-form :headers="request.headers " :request="request" v-if="request.protocol==='HTTP'"/>
<ms-tcp-basis-parameters :request="request" :currentProject="currentProject" v-if="request.protocol==='TCP'"/>
<ms-sql-basis-parameters :request="request" :currentProject="currentProject" v-if="request.protocol==='SQL'"/>
<ms-dubbo-basis-parameters :request="request" :currentProject="currentProject" v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'"/>
<ms-tcp-basis-parameters :request="request" v-if="request.protocol==='TCP'"/>
<ms-sql-basis-parameters :request="request" v-if="request.protocol==='SQL'"/>
<ms-dubbo-basis-parameters :request="request" v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'"/>
<!-- 保存操作 -->
<el-button type="primary" size="small" style="margin: 20px; float: right" @click="saveTestCase(item)" v-if="!request.referenced">
{{$t('commons.save')}}
@ -55,7 +55,6 @@
props: {
request: {},
node: {},
currentProject: {},
},
components: {MsSqlBasisParameters, MsTcpBasisParameters, MsDubboBasisParameters, MsApiRequestForm},
data() {

View File

@ -14,10 +14,9 @@
</el-form>
<!--不同协议请求-->
<ms-debug-http-page :scenario="true" :current-api="request" @saveAs="editApi" :currentProtocol="request.protocol" v-if="request.protocol==='HTTP'"/>
<ms-debug-jdbc-page :scenario="true" :currentProtocol="request.protocol" @saveAs="editApi" :currentProject="currentProject" v-if="request.protocol==='SQL'"/>
<ms-debug-tcp-page :scenario="true" :currentProtocol="request.protocol" @saveAs="editApi" :currentProject="currentProject" v-if="request.protocol==='TCP'"/>
<ms-debug-dubbo-page :scenario="true" :currentProtocol="request.protocol" @saveAs="editApi" :currentProject="currentProject" v-if="request.protocol==='DUBBO'"/>
<ms-debug-jdbc-page :scenario="true" :currentProtocol="request.protocol" @saveAs="editApi" v-if="request.protocol==='SQL'"/>
<ms-debug-tcp-page :scenario="true" :currentProtocol="request.protocol" @saveAs="editApi" v-if="request.protocol==='TCP'"/>
<ms-debug-dubbo-page :scenario="true" :currentProtocol="request.protocol" @saveAs="editApi" v-if="request.protocol==='DUBBO'"/>
</el-card>
</div>
</template>
@ -33,7 +32,6 @@
name: "ApiCustomize",
props: {
node: {},
currentProject: {},
request: {},
},
components: {MsDebugHttpPage, MsDebugJdbcPage, MsDebugTcpPage, MsDebugDubboPage},

View File

@ -25,7 +25,6 @@
props: {
scenario: {},
node: {},
currentProject: {},
},
watch: {},
created() {
@ -70,13 +69,6 @@
color: #606266;
}
.ms-api-col-create {
background-color: #EBF2F2;
border-color: #008080;
margin-right: 10px;
color: #008080;
}
/deep/ .el-card__body {
padding: 15px;
}

View File

@ -66,7 +66,7 @@
<div>
<!-- 执行结果 -->
<el-drawer :visible.sync="runVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('test_track.plan_view.test_result')" :modal="false" size="90%">
<ms-api-report-detail @refresh="search" :infoDb="infoDb" :report-id="reportId" :currentProjectId="currentProject!=undefined ? currentProject.id:''"/>
<ms-api-report-detail @refresh="search" :infoDb="infoDb" :report-id="reportId" :currentProjectId="projectId"/>
</el-drawer>
<!--测试计划-->
<el-drawer :visible.sync="planVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('test_track.plan_view.test_result')" :modal="false" size="90%">
@ -83,7 +83,7 @@
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn";
import MsTag from "../../../common/components/MsTag";
import {getUUID} from "@/common/js/utils";
import {getUUID, getCurrentProjectID} from "@/common/js/utils";
import MsApiReportDetail from "../report/ApiReportDetail";
import MsTableMoreBtn from "./TableMoreBtn";
import MsScenarioExtendButtons from "@/business/components/api/automation/scenario/ScenarioExtendBtns";
@ -93,7 +93,6 @@
name: "MsApiScenarioList",
components: {MsTablePagination, MsTableMoreBtn, ShowMoreBtn, MsTableHeader, MsTag, MsApiReportDetail, MsScenarioExtendButtons, MsTestPlanList},
props: {
currentProject: Object,
currentModule: Object,
referenced: {
type: Boolean,
@ -116,6 +115,7 @@
infoDb: false,
runVisible: false,
planVisible: false,
projectId: "",
runData: [],
buttons: [
{
@ -126,10 +126,11 @@
],
}
},
created() {
this.projectId = getCurrentProjectID();
this.search();
},
watch: {
currentProject() {
this.search();
},
currentModule() {
this.search();
},
@ -148,8 +149,8 @@
this.condition.moduleIds = this.currentModule.ids;
}
}
if (this.currentProject != null) {
this.condition.projectId = this.currentProject.id;
if (this.projectId != null) {
this.condition.projectId = this.projectId;
}
let url = "/api/automation/list/" + this.currentPage + "/" + this.pageSize;

View File

@ -1,10 +1,5 @@
<template>
<div>
<select-menu
:data="projects"
:current-data="currentProject"
:title="$t('test_track.project')"
@dataChange="changeProject" style="margin-bottom: 20px"/>
<el-input style="width: 275px;" :placeholder="$t('test_track.module.search')" v-model="filterText"
size="small">
<template v-slot:append>
@ -81,381 +76,365 @@
</template>
<script>
import SelectMenu from "../../../track/common/SelectMenu";
import MsAddBasisScenario from "@/business/components/api/automation/scenario/AddBasisScenario";
import SelectMenu from "../../../track/common/SelectMenu";
import MsAddBasisScenario from "@/business/components/api/automation/scenario/AddBasisScenario";
import {getCurrentProjectID} from "@/common/js/utils";
export default {
name: 'MsApiScenarioModule',
components: {
MsAddBasisScenario,
SelectMenu,
},
data() {
return {
httpVisible: false,
expandedNode: [],
filterText: "",
nextFlag: true,
currentProject: {},
projects: [],
currentModule: {},
newLabel: "",
data: [{
"id": "gc",
"name": "回收站",
"level": 1,
"children": [],
}, {
"id": "root",
"name": "默认模块",
"level": 0,
"children": [],
}]
}
},
mounted() {
this.getProjects();
this.changeProtocol();
},
watch: {
currentProject() {
this.getApiModuleTree();
this.$emit('changeProject', this.currentProject);
export default {
name: 'MsApiScenarioModule',
components: {
MsAddBasisScenario,
SelectMenu,
},
filterText(val) {
this.$refs.tree.filter(val);
}
},
methods: {
getApiModuleTree() {
if (this.currentProject) {
if (this.expandedNode.length === 0) {
this.expandedNode.push("root");
}
this.$get("/api/automation/module/list/" + this.currentProject.id, response => {
if (response.data !== undefined && response.data !== null) {
this.data[1].children = response.data;
let moduleOptions = [];
this.data[1].children.forEach(node => {
this.buildNodePath(node, {path: ''}, moduleOptions);
});
this.$emit('getApiModuleTree', moduleOptions);
data() {
return {
httpVisible: false,
expandedNode: [],
filterText: "",
nextFlag: true,
currentModule: {},
newLabel: "",
data: [{
"id": "gc",
"name": "回收站",
"level": 1,
"children": [],
}, {
"id": "root",
"name": "默认模块",
"level": 0,
"children": [],
}]
}
},
mounted() {
this.changeProtocol();
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
methods: {
getApiModuleTree() {
let projectId = getCurrentProjectID();
if (projectId) {
if (this.expandedNode.length === 0) {
this.expandedNode.push("root");
}
});
}
},
buildNodePath(node, option, moduleOptions) {
//
option.id = node.id;
option.path = option.path + '/' + node.name;
node.path = option.path;
moduleOptions.push(option);
if (node.children) {
for (let i = 0; i < node.children.length; i++) {
this.buildNodePath(node.children[i], {path: option.path}, moduleOptions);
this.$get("/api/automation/module/list/" + projectId, response => {
if (response.data !== undefined && response.data !== null) {
this.data[1].children = response.data;
let moduleOptions = [];
this.data[1].children.forEach(node => {
this.buildNodePath(node, {path: ''}, moduleOptions);
});
this.$emit('getApiModuleTree', moduleOptions);
}
});
}
}
},
findTreeByNodeId(rootNode, nodeId) {
if (rootNode.id === nodeId) {
return rootNode;
}
if (rootNode.children) {
for (let i = 0; i < rootNode.children.length; i++) {
if (this.findTreeByNodeId(rootNode.children[i], nodeId)) {
return rootNode;
},
buildNodePath(node, option, moduleOptions) {
//
option.id = node.id;
option.path = option.path + '/' + node.name;
node.path = option.path;
moduleOptions.push(option);
if (node.children) {
for (let i = 0; i < node.children.length; i++) {
this.buildNodePath(node.children[i], {path: option.path}, moduleOptions);
}
}
}
},
buildParam(draggingNode, dropNode, dropType) {
let param = {};
param.id = draggingNode.data.id;
param.name = draggingNode.data.name;
param.projectId = draggingNode.data.projectId;
if (dropType === "inner") {
param.parentId = dropNode.data.id;
param.level = dropNode.data.level;
} else {
if (!dropNode.parent.id || dropNode.parent.id === 0) {
param.parentId = 0;
param.level = 1;
},
findTreeByNodeId(rootNode, nodeId) {
if (rootNode.id === nodeId) {
return rootNode;
}
if (rootNode.children) {
for (let i = 0; i < rootNode.children.length; i++) {
if (this.findTreeByNodeId(rootNode.children[i], nodeId)) {
return rootNode;
}
}
}
},
buildParam(draggingNode, dropNode, dropType) {
let param = {};
param.id = draggingNode.data.id;
param.name = draggingNode.data.name;
param.projectId = draggingNode.data.projectId;
if (dropType === "inner") {
param.parentId = dropNode.data.id;
param.level = dropNode.data.level;
} else {
param.parentId = dropNode.parent.data.id;
param.level = dropNode.parent.data.level;
}
}
let nodeIds = [];
this.getChildNodeId(draggingNode.data, nodeIds);
if (dropNode.level === 1 && dropType !== "inner") {
param.nodeTree = draggingNode.data;
} else {
for (let i = 0; i < this.data.length; i++) {
param.nodeTree = this.findTreeByNodeId(this.data[i], dropNode.data.id);
if (param.nodeTree) {
break;
if (!dropNode.parent.id || dropNode.parent.id === 0) {
param.parentId = 0;
param.level = 1;
} else {
param.parentId = dropNode.parent.data.id;
param.level = dropNode.parent.data.level;
}
}
}
param.nodeIds = nodeIds;
return param;
},
getTreeNode(nodes, id, list) {
if (!nodes) {
return;
}
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].id === id) {
i - 1 >= 0 ? list[0] = nodes[i - 1].id : list[0] = "";
list[1] = nodes[i].id;
i + 1 < nodes.length ? list[2] = nodes[i + 1].id : list[2] = "";
return;
}
if (nodes[i].children) {
this.getTreeNode(nodes[i].children, id, list);
}
}
},
handleDragEnd(draggingNode, dropNode, dropType) {
if (dropNode.data.id === "root" || dropType === "none" || dropType === undefined) {
return;
}
let param = this.buildParam(draggingNode, dropNode, dropType);
this.list = [];
if (param.parentId === "root") {
param.parentId = null;
}
this.getTreeNode(this.data, draggingNode.data.id, this.list);
this.$post("/api/automation/module/drag", param, () => {
this.getApiModuleTree();
}, () => {
this.getApiModuleTree();
});
},
allowDrop(draggingNode, dropNode) {
return dropNode.data.id !== "root";
},
allowDrag(draggingNode) {
//
return draggingNode.data.id !== "root";
},
append(node, data) {
if (this.nextFlag === true) {
const newChild = {
id: "newId",
isEdit: 0,
name: "",
children: []
}
if (!data.children) {
this.$set(data, 'children', [])
}
this.nextFlag = false;
data.children.push(newChild)
this.edit(node, newChild);
} else {
this.$message.warning(this.$t('commons.please_save'));
}
},
remove(node, data) {
if (data.name === "") {
this.nextFlag = true;
}
let delIds = [];
this.getChildNodeId(data, delIds);
delIds.push(data.id);
this.$post("/api/automation/module/delete", delIds, () => {
this.$success(this.$t('commons.save_success'));
//
const parent = node.parent
const children = parent.data.children || parent.data
const index = children.findIndex(d => d.id !== undefined && data.id !== undefined && d.id === data.id)
children.splice(index, 1);
});
},
edit(node, data) {
this.$set(data, 'isEdit', 1)
this.newLabel = data.name
this.$nextTick(() => {
})
},
submitEdit(node, data) {
//
if (this.newLabel === "") {
this.nextFlag = false;
this.$message.warning(this.$t('commons.input_name'));
return;
}
this.$set(data, 'name', this.newLabel)
let flag = this.editApiModule(node, data);
if (flag === false) {
this.$set(data, 'isEdit', 1)
return;
}
this.$set(data, 'isEdit', 0)
this.newLabel = ""
this.nextFlag = true;
},
cancelEdit(node, data) {
this.newLabel = ""
this.$set(data, 'isEdit', 0)
},
getChildNodeId(rootNode, nodeIds) {
//ID
nodeIds.push(rootNode.id);
this.nodePath += rootNode.name + "/";
if (rootNode.children) {
for (let i = 0; i < rootNode.children.length; i++) {
this.getChildNodeId(rootNode.children[i], nodeIds);
}
}
},
//
editApiModule(node, data) {
if (!this.currentProject) {
this.$error("$t('api_test.select_project')");
return;
}
let url = "";
if (data.id === "newId") {
url = '/api/automation/module/add';
data.level = 1;
if (node.parent && node.parent.key !== "root") {
data.parentId = node.parent.key;
data.level = node.parent.level;
}
} else {
url = '/api/automation/module/edit';
let ids = [];
this.getChildNodeId(data, ids);
data.nodeIds = ids;
}
data.protocol = this.protocol;
data.projectId = this.currentProject.id;
this.$post(url, data, () => {
this.$success(this.$t('commons.save_success'));
this.getApiModuleTree();
this.nextFlag = true;
return true;
});
return false;
},
selectModule(data) {
if (data.id !== "root") {
if (data.path !== undefined && !data.path.startsWith("/")) {
data.path = "/" + data.path;
}
if (data.path !== undefined && data.path.endsWith("/")) {
data.path = data.path.substr(0, data.path.length - 1);
}
let nodeIds = [];
this.getChildNodeId(data, nodeIds);
data.ids = nodeIds;
this.currentModule = data;
}
this.$emit('selectModule', data);
},
refresh(data) {
this.$emit('refresh', data);
},
saveAsEdit(data) {
this.$emit('saveAsEdit', data);
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
addScenario() {
this.$refs.basisScenario.open(this.currentModule, this.currentProject.id);
},
//
changeProject(project) {
this.currentProject = project;
},
getProjects() {
this.$get("/project/listAll", (response) => {
this.projects = response.data;
if (this.projects.length > 0) {
this.currentProject = this.projects[0];
this.getChildNodeId(draggingNode.data, nodeIds);
if (dropNode.level === 1 && dropType !== "inner") {
param.nodeTree = draggingNode.data;
} else {
for (let i = 0; i < this.data.length; i++) {
param.nodeTree = this.findTreeByNodeId(this.data[i], dropNode.data.id);
if (param.nodeTree) {
break;
}
}
}
});
},
nodeExpand(data) {
if (data.id) {
this.expandedNode.push(data.id);
param.nodeIds = nodeIds;
return param;
},
getTreeNode(nodes, id, list) {
if (!nodes) {
return;
}
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].id === id) {
i - 1 >= 0 ? list[0] = nodes[i - 1].id : list[0] = "";
list[1] = nodes[i].id;
i + 1 < nodes.length ? list[2] = nodes[i + 1].id : list[2] = "";
return;
}
if (nodes[i].children) {
this.getTreeNode(nodes[i].children, id, list);
}
}
},
handleDragEnd(draggingNode, dropNode, dropType) {
if (dropNode.data.id === "root" || dropType === "none" || dropType === undefined) {
return;
}
let param = this.buildParam(draggingNode, dropNode, dropType);
this.list = [];
if (param.parentId === "root") {
param.parentId = null;
}
this.getTreeNode(this.data, draggingNode.data.id, this.list);
this.$post("/api/automation/module/drag", param, () => {
this.getApiModuleTree();
}, () => {
this.getApiModuleTree();
});
},
allowDrop(draggingNode, dropNode) {
return dropNode.data.id !== "root";
},
allowDrag(draggingNode) {
//
return draggingNode.data.id !== "root";
},
append(node, data) {
if (this.nextFlag === true) {
const newChild = {
id: "newId",
isEdit: 0,
name: "",
children: []
}
if (!data.children) {
this.$set(data, 'children', [])
}
this.nextFlag = false;
data.children.push(newChild)
this.edit(node, newChild);
} else {
this.$message.warning(this.$t('commons.please_save'));
}
},
remove(node, data) {
if (data.name === "") {
this.nextFlag = true;
}
let delIds = [];
this.getChildNodeId(data, delIds);
delIds.push(data.id);
this.$post("/api/automation/module/delete", delIds, () => {
this.$success(this.$t('commons.save_success'));
//
const parent = node.parent
const children = parent.data.children || parent.data
const index = children.findIndex(d => d.id !== undefined && data.id !== undefined && d.id === data.id)
children.splice(index, 1);
});
},
edit(node, data) {
this.$set(data, 'isEdit', 1)
this.newLabel = data.name
this.$nextTick(() => {
})
},
submitEdit(node, data) {
//
if (this.newLabel === "") {
this.nextFlag = false;
this.$message.warning(this.$t('commons.input_name'));
return;
}
this.$set(data, 'name', this.newLabel)
let flag = this.editApiModule(node, data);
if (flag === false) {
this.$set(data, 'isEdit', 1)
return;
}
this.$set(data, 'isEdit', 0)
this.newLabel = ""
this.nextFlag = true;
},
cancelEdit(node, data) {
this.newLabel = ""
this.$set(data, 'isEdit', 0)
},
getChildNodeId(rootNode, nodeIds) {
//ID
nodeIds.push(rootNode.id);
this.nodePath += rootNode.name + "/";
if (rootNode.children) {
for (let i = 0; i < rootNode.children.length; i++) {
this.getChildNodeId(rootNode.children[i], nodeIds);
}
}
},
//
editApiModule(node, data) {
let projectId = getCurrentProjectID();
if (!projectId) {
this.$error("$t('api_test.select_project')");
return;
}
let url = "";
if (data.id === "newId") {
url = '/api/automation/module/add';
data.level = 1;
if (node.parent && node.parent.key !== "root") {
data.parentId = node.parent.key;
data.level = node.parent.level;
}
} else {
url = '/api/automation/module/edit';
let ids = [];
this.getChildNodeId(data, ids);
data.nodeIds = ids;
}
data.protocol = this.protocol;
data.projectId = projectId;
this.$post(url, data, () => {
this.$success(this.$t('commons.save_success'));
this.getApiModuleTree();
this.nextFlag = true;
return true;
});
return false;
},
selectModule(data) {
if (data.id !== "root") {
if (data.path !== undefined && !data.path.startsWith("/")) {
data.path = "/" + data.path;
}
if (data.path !== undefined && data.path.endsWith("/")) {
data.path = data.path.substr(0, data.path.length - 1);
}
let nodeIds = [];
this.getChildNodeId(data, nodeIds);
data.ids = nodeIds;
this.currentModule = data;
}
this.$emit('selectModule', data);
},
refresh(data) {
this.$emit('refresh', data);
},
saveAsEdit(data) {
this.$emit('saveAsEdit', data);
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
addScenario() {
this.$refs.basisScenario.open(this.currentModule);
},
nodeExpand(data) {
if (data.id) {
this.expandedNode.push(data.id);
}
},
nodeCollapse(data) {
if (data.id) {
this.expandedNode.splice(this.expandedNode.indexOf(data.id), 1);
}
},
changeProtocol() {
this.getApiModuleTree();
this.$emit('changeProtocol', this.protocol);
}
},
nodeCollapse(data) {
if (data.id) {
this.expandedNode.splice(this.expandedNode.indexOf(data.id), 1);
}
},
changeProtocol() {
this.getApiModuleTree();
this.$emit('changeProtocol', this.protocol);
}
}
}
</script>
<style scoped>
.node-tree {
margin-top: 15px;
margin-bottom: 15px;
}
.node-tree {
margin-top: 15px;
margin-bottom: 15px;
}
.ms-el-input {
height: 25px;
line-height: 25px;
}
.ms-el-input {
height: 25px;
line-height: 25px;
}
.custom-tree-node {
flex: 1 1 auto;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
width: 100%;
}
.custom-tree-node {
flex: 1 1 auto;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
width: 100%;
}
.father .child {
display: none;
}
.father .child {
display: none;
}
.father:hover .child {
display: block;
}
.father:hover .child {
display: block;
}
.node-title {
width: 0;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1 1 auto;
padding: 0 5px;
overflow: hidden;
}
.node-title {
width: 0;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1 1 auto;
padding: 0 5px;
overflow: hidden;
}
.node-operate > i {
color: #409eff;
margin: 0 5px;
}
.node-operate > i {
color: #409eff;
margin: 0 5px;
}
/deep/ .el-tree-node__content {
height: 33px;
}
/deep/ .el-tree-node__content {
height: 33px;
}
.ms-api-buttion {
width: 30px;
}
.ms-api-buttion {
width: 30px;
}
</style>

View File

@ -187,7 +187,7 @@
<!--提取规则-->
<ms-api-extract @remove="remove" v-if="data.type==='Extract'" customizeStyle="margin-top: 0px" :extract="data" :node="node"/>
<!--API 导入 -->
<ms-api-component :request="data" @remove="remove" current-project="currentProject" v-if="data.type==='HTTPSamplerProxy'||data.type==='DubboSampler'||data.type==='JDBCSampler'||data.type==='TCPSampler'" :node="node"/>
<ms-api-component :request="data" @remove="remove" v-if="data.type==='HTTPSamplerProxy'||data.type==='DubboSampler'||data.type==='JDBCSampler'||data.type==='TCPSampler'" :node="node"/>
</template>
</span>
</el-tree>
@ -245,7 +245,7 @@
<!--自定义接口-->
<el-drawer :visible.sync="customizeVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.customize_req')" style="overflow: auto" :modal="false" size="90%">
<ms-api-customize :request="customizeRequest" @addCustomizeApi="addCustomizeApi" :current-project="currentProject"/>
<ms-api-customize :request="customizeRequest" @addCustomizeApi="addCustomizeApi" />
<!--<el-button style="float: right;margin: 20px" @click="addCustomizeApi">{{$t('commons.save')}}</el-button>-->
</el-drawer>
<!--场景导入 -->
@ -263,7 +263,7 @@
@runRefresh="runRefresh" ref="runTest"/>
<!-- 调试结果 -->
<el-drawer :visible.sync="debugVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('test_track.plan_view.test_result')" :modal="false" size="90%">
<ms-api-report-detail :report-id="reportId" :debug="true" :currentProjectId="currentProject.id"/>
<ms-api-report-detail :report-id="reportId" :debug="true" :currentProjectId="projectId"/>
</el-drawer>
<!--场景公共参数-->
@ -286,7 +286,7 @@
import MsApiComponent from "./ApiComponent";
import {ELEMENTS, ELEMENT_TYPE} from "./Setting";
import MsApiCustomize from "./ApiCustomize";
import {getUUID} from "@/common/js/utils";
import {getUUID, getCurrentProjectID} from "@/common/js/utils";
import ApiEnvironmentConfig from "../../definition/components/environment/ApiEnvironmentConfig";
import MsAddTag from "./AddTag";
import MsRun from "./DebugRun";
@ -295,12 +295,10 @@
import MsApiReportDetail from "../report/ApiReportDetail";
import MsScenarioParameters from "./ScenarioParameters";
export default {
name: "EditApiScenario",
props: {
moduleOptions: Array,
currentProject: {},
currentScenario: {},
},
components: {
@ -350,9 +348,11 @@
path: "/api/automation/create",
debugData: {},
reportId: "",
projectId: "",
}
},
created() {
this.projectId = getCurrentProjectID();
this.operatingElements = ELEMENTS.get("ALL");
this.getMaintainerOptions();
this.refreshTags();
@ -514,14 +514,14 @@
},
openTagConfig() {
if (!this.currentProject) {
if (!this.projectId) {
this.$error(this.$t('api_test.select_project'));
return;
}
this.$refs.tag.open(this.currentProject.id);
this.$refs.tag.open();
},
refreshTags() {
let obj = {projectId: this.currentProject.id};
let obj = {projectId: this.projectId};
let tagIds = [];
this.$post('/api/tag/list', obj, response => {
this.tags = response.data;
@ -562,8 +562,8 @@
this.reportId = getUUID().substring(0, 8);
},
getEnvironments() {
if (this.currentProject) {
this.$get('/api/environment/list/' + this.currentProject.id, response => {
if (this.projectId) {
this.$get('/api/environment/list/' + this.projectId, response => {
this.environments = response.data;
this.environments.forEach(environment => {
parseEnvironment(environment);
@ -572,11 +572,11 @@
}
},
openEnvironmentConfig() {
if (!this.currentProject) {
if (!this.projectId) {
this.$error(this.$t('api_test.select_project'));
return;
}
this.$refs.environmentConfig.open(this.currentProject.id);
this.$refs.environmentConfig.open(this.projectId);
},
environmentConfigClose() {
this.getEnvironments();
@ -696,7 +696,7 @@
}
},
setParameter() {
this.currentScenario.projectId = this.currentProject.id;
this.currentScenario.projectId = this.projectId;
if (!this.currentScenario.id) {
this.currentScenario.id = getUUID();
}

View File

@ -1,12 +1,11 @@
<template>
<ms-container>
<ms-aside-container>
<ms-api-scenario-module @selectModule="selectModule" @getApiModuleTree="initTree" @changeProject="changeProject"
<ms-api-scenario-module @selectModule="selectModule" @getApiModuleTree="initTree"
@refresh="refresh" @saveAsEdit="editScenario"/>
</ms-aside-container>
<ms-main-container>
<ms-api-scenario-list
:current-project="currentProject"
:current-module="currentModule"
@edit="editScenario"
@selection="setData"
@ -37,7 +36,6 @@
return {
isHide: true,
activeName: 'default',
currentProject: null,
currentModule: null,
currentScenario: [],
currentScenarioIds: [],
@ -85,9 +83,6 @@
initTree(data) {
this.moduleOptions = data;
},
changeProject(data) {
this.currentProject = data;
},
refresh(data) {
this.$refs.apiScenarioList.search(data);
},

View File

@ -27,7 +27,6 @@
import {getUUID} from "@/common/js/utils";
import {createComponent, Request} from "./jmeter/components";
import Sampler from "./jmeter/components/sampler/sampler";
import HeaderManager from "./jmeter/components/configurations/header-manager";
import {WORKSPACE_ID} from '@/common/js/constants';
export default {

View File

@ -12,7 +12,7 @@
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
<!-- TCP 请求参数 -->
<ms-basis-parameters :request="request" :currentProject="currentProject" ref="requestForm"/>
<ms-basis-parameters :request="request" ref="requestForm"/>
<!-- TCP 请求返回数据 -->
@ -45,7 +45,6 @@
components: {MsRequestResultTail, MsResponseResult, MsApiRequestForm, MsRequestMetric, MsResponseText, MsRun, MsBasisParameters},
props: {
currentProtocol: String,
currentProject: {},
scenario: Boolean,
},
data() {

View File

@ -12,7 +12,7 @@
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
<!-- JDBC 请求参数 -->
<ms-basis-parameters :request="request" @callback="runDebug" :currentProject="currentProject" ref="requestForm"/>
<ms-basis-parameters :request="request" @callback="runDebug" ref="requestForm"/>
<!-- JDBC 请求返回数据 -->
@ -47,7 +47,6 @@
components: {MsRequestResultTail, MsResponseResult, MsApiRequestForm, MsRequestMetric, MsResponseText, MsRun, MsBasisParameters},
props: {
currentProtocol: String,
currentProject: {},
scenario: Boolean,
},
data() {

View File

@ -12,7 +12,7 @@
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
<!-- TCP 请求参数 -->
<ms-basis-parameters :request="request" @callback="runDebug" :currentProject="currentProject" ref="requestForm"/>
<ms-basis-parameters :request="request" @callback="runDebug" ref="requestForm"/>
<!-- TCP 请求返回数据 -->
@ -46,7 +46,6 @@
components: {MsRequestResultTail, MsResponseResult, MsApiRequestForm, MsRequestMetric, MsResponseText, MsRun, MsBasisParameters},
props: {
currentProtocol: String,
currentProject: {},
scenario: Boolean,
},
data() {

View File

@ -117,7 +117,6 @@
props: {
request: {},
basisData: {},
currentProject: {},
moduleOptions: Array,
isReadOnly: {
type: Boolean,

View File

@ -100,7 +100,6 @@
props: {
request: {},
basisData: {},
currentProject: {},
moduleOptions: Array,
isReadOnly: {
type: Boolean,
@ -148,10 +147,6 @@
})
},
validateApi() {
if (this.currentProject === null) {
this.$error(this.$t('api_test.select_project'), 2000);
return;
}
this.$refs['basicForm'].validate();
},
saveApi() {
@ -185,6 +180,7 @@
/deep/ .el-form-item {
margin-bottom: 15px;
}
.ms-left-cell {
margin-top: 40px;
}

View File

@ -132,6 +132,7 @@
import ApiEnvironmentConfig from "../../environment/ApiEnvironmentConfig";
import {API_STATUS} from "../../../model/JsonData";
import TCPSampler from "../../jmeter/components/sampler/tcp-sampler";
import {getCurrentProjectID} from "@/common/js/utils";
export default {
name: "MsDatabaseConfig",
@ -143,7 +144,6 @@
props: {
request: {},
basisData: {},
currentProject: {},
moduleOptions: Array,
isReadOnly: {
type: Boolean,
@ -156,6 +156,7 @@
classes: TCPSampler.CLASSES,
isReloadData: false,
options: API_STATUS,
currentProjectId: "",
rules: {
classname: [{required: true, message: "请选择TCPClient", trigger: 'change'}],
server: [{required: true, message: this.$t('api_test.request.tcp.server_cannot_be_empty'), trigger: 'blur'}],
@ -164,6 +165,7 @@
}
},
created() {
this.currentProjectId = getCurrentProjectID();
this.getEnvironments();
},
methods: {
@ -199,7 +201,7 @@
})
},
validateApi() {
if (this.currentProject === null) {
if (this.currentProjectId === null) {
this.$error(this.$t('api_test.select_project'), 2000);
return;
}
@ -213,7 +215,7 @@
},
validate() {
if (this.currentProject === null) {
if (this.currentProjectId === null) {
this.$error(this.$t('api_test.select_project'), 2000);
return;
}
@ -224,9 +226,9 @@
})
},
getEnvironments() {
if (this.currentProject) {
if (this.currentProjectId) {
this.environments = [];
this.$get('/api/environment/list/' + this.currentProject.id, response => {
this.$get('/api/environment/list/' + this.currentProjectId, response => {
this.environments = response.data;
this.environments.forEach(environment => {
parseEnvironment(environment);
@ -236,11 +238,11 @@
}
},
openEnvironmentConfig() {
if (!this.currentProject) {
if (!this.currentProjectId) {
this.$error(this.$t('api_test.select_project'));
return;
}
this.$refs.environmentConfig.open(this.currentProject.id);
this.$refs.environmentConfig.open(this.currentProjectId);
},
initDataSource() {
for (let i in this.environments) {

View File

@ -6,7 +6,8 @@ import {
ROLE_TEST_MANAGER,
ROLE_TEST_USER,
ROLE_TEST_VIEWER,
TokenKey
TokenKey,
PROJECT_ID
} from "./constants";
import axios from "axios";
import {jsPDF} from "jspdf";
@ -88,6 +89,10 @@ export function getCurrentUser() {
return JSON.parse(localStorage.getItem(TokenKey));
}
export function getCurrentProjectID() {
return localStorage.getItem(PROJECT_ID);
}
export function saveLocalStorage(response) {
// 登录信息保存 cookie
localStorage.setItem(TokenKey, JSON.stringify(response.data));