style(接口测试): 使用Prettier自定义标准格式化

This commit is contained in:
fit2-zhao 2022-11-21 15:17:14 +08:00 committed by fit2-zhao
parent b9ef0e384f
commit 2ca90f3136
320 changed files with 5221 additions and 17499 deletions

View File

@ -0,0 +1,20 @@
{
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "es5",
"bracketSpacing": true,
"bracketSameLine": true,
"jsxBracketSameLine": true,
"arrowParens": "always",
"rangeStart": 0,
"requirePragma": false,
"insertPragma": false,
"htmlWhitespaceSensitivity": "css",
"vueIndentScriptAndStyle": false,
"endOfLine": "lf",
"printWidth": 120,
"proseWrap": "never"
}

View File

@ -10,9 +10,8 @@
<body>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please
enable it to continue.</strong
>
</noscript>
<div id="app"></div>

View File

@ -23,10 +23,7 @@ export function fileUpload(url, file, files, param) {
formData.append('files', f);
});
}
formData.append(
'request',
new Blob([JSON.stringify(param)], { type: 'application/json' })
);
formData.append('request', new Blob([JSON.stringify(param)], { type: 'application/json' }));
let config = getUploadConfig(url, formData);
return request(config);
}
@ -45,9 +42,7 @@ export function downloadFile(method, url, data, fileName) {
};
request(config)
.then((res) => {
fileName = fileName
? fileName
: window.decodeURI(res.headers['content-disposition'].split('=')[1]);
fileName = fileName ? fileName : window.decodeURI(res.headers['content-disposition'].split('=')[1]);
jsFileDownload(res.data, fileName);
})
.catch((e) => {

View File

@ -1,12 +1,7 @@
import { get, post } from 'metersphere-frontend/src/plugins/request';
export function getApiModules(projectId, protocol, currentVersion) {
let url =
'/api/module/list/' +
projectId +
'/' +
protocol +
(currentVersion ? '/' + currentVersion : '');
let url = '/api/module/list/' + projectId + '/' + protocol + (currentVersion ? '/' + currentVersion : '');
return get(url);
}
@ -16,13 +11,7 @@ export function getApiModuleByProjectIdAndProtocol(projectId, protocol) {
}
export function getApiModuleByTrash(projectId, protocol, currentVersion) {
let url =
'/api/module/trash/list/' +
projectId +
'/' +
protocol +
'/' +
(currentVersion ? '/' + currentVersion : '');
let url = '/api/module/trash/list/' + projectId + '/' + protocol + '/' + (currentVersion ? '/' + currentVersion : '');
return get(url);
}

View File

@ -62,16 +62,11 @@ export function apiListBatch(params) {
}
export function definitionWeekList(projectId, page, pageSize) {
return post(
'/api/definition/list/week/' + projectId + '/' + page + '/' + pageSize
);
return post('/api/definition/list/week/' + projectId + '/' + page + '/' + pageSize);
}
export function getRelevanceDefinitionPage(page, pageSize, params) {
return post(
'/api/definition/list/relevance/' + page + '/' + pageSize,
params
);
return post('/api/definition/list/relevance/' + page + '/' + pageSize, params);
}
export function getDefinitionPage(page, pageSize, params) {
@ -115,10 +110,7 @@ export function definitionReduction(params) {
}
export function definitionRelationship(currentPage, pageSize, params) {
return post(
'/api/definition/relationship/relate/' + currentPage + '/' + pageSize,
params
);
return post('/api/definition/relationship/relate/' + currentPage + '/' + pageSize, params);
}
export function addRelationship(params) {
@ -130,17 +122,11 @@ export function jsonGenerator(params) {
}
export function getDefinitionReference(currentPage, pageSize, params) {
return post(
'/api/definition/get-reference/' + currentPage + '/' + pageSize,
params
);
return post('/api/definition/get-reference/' + currentPage + '/' + pageSize, params);
}
export function getPlanReference(currentPage, pageSize, params) {
return post(
'/test/plan/api/case/get-reference/' + currentPage + '/' + pageSize,
params
);
return post('/test/plan/api/case/get-reference/' + currentPage + '/' + pageSize, params);
}
export function deleteBatchByParams(params) {

View File

@ -31,15 +31,7 @@ export function genPerformanceTestXml(file, files, params) {
}
export function getRunningTask(selectProjectId, currentPage, pageSize, param) {
return post(
'/task/center/runningTask/' +
selectProjectId +
'/' +
currentPage +
'/' +
pageSize,
param
);
return post('/task/center/runningTask/' + selectProjectId + '/' + currentPage + '/' + pageSize, param);
}
export function formatNumber(param) {

View File

@ -1,8 +1,4 @@
import {
post,
generateShareUrl,
get,
} from 'metersphere-frontend/src/plugins/request';
import { post, generateShareUrl, get } from 'metersphere-frontend/src/plugins/request';
export function generateApiDocumentShareInfo(param) {
return post('/share/generate/api/document', param);
@ -22,9 +18,7 @@ export function getShareContent(shareId, stepId) {
}
export function getShareApiReport(shareId, testId) {
return get(
'/share/api/definition/report/getReport/' + shareId + '/' + testId
);
return get('/share/api/definition/report/getReport/' + shareId + '/' + testId);
}
export function getShareInfo(id) {

View File

@ -16,21 +16,11 @@
:is-trash-data="trashEnable"
:type="'edit'"
:total="total"
ref="nodeTree"
/>
ref="nodeTree" />
</ms-aside-container>
<ms-main-container>
<el-tabs
v-model="activeName"
@tab-click="addTab"
@tab-remove="closeConfirm"
>
<el-tab-pane
name="trash"
:closable="true"
:label="$t('commons.trash')"
v-if="trashEnable"
>
<el-tabs v-model="activeName" @tab-click="addTab" @tab-remove="closeConfirm">
<el-tab-pane name="trash" :closable="true" :label="$t('commons.trash')" v-if="trashEnable">
<ms-api-scenario-list
@getTrashCase="getTrashCase"
@refreshTree="refreshTree"
@ -47,21 +37,13 @@
:custom-num="customNum"
:init-api-table-opretion="initApiTableOpretion"
@updateInitApiTableOpretion="updateInitApiTableOpretion"
ref="apiTrashScenarioList"
>
ref="apiTrashScenarioList">
<template v-slot:version>
<mx-version-select
v-xpack
:project-id="projectId"
@changeVersion="changeVersion"
/>
<mx-version-select v-xpack :project-id="projectId" @changeVersion="changeVersion" />
</template>
</ms-api-scenario-list>
</el-tab-pane>
<el-tab-pane
name="default"
:label="$t('api_test.automation.scenario_list')"
>
<el-tab-pane name="default" :label="$t('api_test.automation.scenario_list')">
<ms-api-scenario-list
v-if="!trashEnable"
@getTrashCase="getTrashCase"
@ -79,32 +61,20 @@
:custom-num="customNum"
:init-api-table-opretion="initApiTableOpretion"
@updateInitApiTableOpretion="updateInitApiTableOpretion"
ref="apiScenarioList"
>
ref="apiScenarioList">
<template v-slot:version>
<mx-version-select
v-xpack
:project-id="projectId"
@changeVersion="changeVersion"
/>
<mx-version-select v-xpack :project-id="projectId" @changeVersion="changeVersion" />
</template>
</ms-api-scenario-list>
</el-tab-pane>
<el-tab-pane
:key="item.name"
v-for="item in tabs"
:label="item.label"
:name="item.name"
closable
>
<el-tab-pane :key="item.name" v-for="item in tabs" :label="item.label" :name="item.name" closable>
<el-tooltip
slot="label"
effect="dark"
:content="item.label"
placement="bottom-start"
class="ms-tab-name-width"
>
class="ms-tab-name-width">
<span>{{ item.label }}</span>
</el-tooltip>
<div class="ms-api-scenario-div">
@ -115,23 +85,16 @@
:currentScenario="item.currentScenario"
:custom-num="customNum"
:moduleOptions="moduleOptions"
ref="autoScenarioConfig"
/>
ref="autoScenarioConfig" />
</div>
</el-tab-pane>
<el-tab-pane
name="add"
v-if="hasPermission('PROJECT_API_SCENARIO:READ+CREATE')"
>
<el-tab-pane name="add" v-if="hasPermission('PROJECT_API_SCENARIO:READ+CREATE')">
<template v-slot:label>
<el-dropdown @command="handleCommand">
<el-button type="primary" plain icon="el-icon-plus" size="mini" />
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
command="ADD"
v-permission="['PROJECT_API_SCENARIO:READ+CREATE']"
>
<el-dropdown-item command="ADD" v-permission="['PROJECT_API_SCENARIO:READ+CREATE']">
{{ $t('api_test.automation.add_scenario') }}
</el-dropdown-item>
<el-dropdown-item command="CLOSE_ALL"
@ -147,24 +110,13 @@
</template>
<script>
import {
getCurrentProjectID,
getCurrentUser,
getCurrentWorkspaceId,
} from 'metersphere-frontend/src/utils/token';
import { getCurrentProjectID, getCurrentUser, getCurrentWorkspaceId } from 'metersphere-frontend/src/utils/token';
import { getUUID } from 'metersphere-frontend/src/utils';
import { hasPermission } from 'metersphere-frontend/src/utils/permission';
import {
PROJECT_ID,
WORKSPACE_ID,
} from 'metersphere-frontend/src/utils/constants';
import { PROJECT_ID, WORKSPACE_ID } from 'metersphere-frontend/src/utils/constants';
import { buildTree } from 'metersphere-frontend/src/model/NodeTree';
import { getScenarioById, getScenarioByTrash } from '@/api/scenario';
import {
getOwnerProjectIds,
getProject,
getProjectConfig,
} from '@/api/project';
import { getOwnerProjectIds, getProject, getProjectConfig } from '@/api/project';
import { getModuleByProjectId } from '@/api/scenario-module';
import { useApiStore } from '@/store';
@ -173,18 +125,12 @@ const jsondiffpatch = require('jsondiffpatch');
export default {
name: 'ApiAutomation',
components: {
MxVersionSelect: () =>
import('metersphere-frontend/src/components/version/MxVersionSelect'),
MsApiScenarioModule: () =>
import('@/business/automation/scenario/ApiScenarioModule'),
MsApiScenarioList: () =>
import('@/business/automation/scenario/ApiScenarioList'),
MsMainContainer: () =>
import('metersphere-frontend/src/components/MsMainContainer'),
MsAsideContainer: () =>
import('metersphere-frontend/src/components/MsAsideContainer'),
MsContainer: () =>
import('metersphere-frontend/src/components/MsContainer'),
MxVersionSelect: () => import('metersphere-frontend/src/components/version/MxVersionSelect'),
MsApiScenarioModule: () => import('@/business/automation/scenario/ApiScenarioModule'),
MsApiScenarioList: () => import('@/business/automation/scenario/ApiScenarioList'),
MsMainContainer: () => import('metersphere-frontend/src/components/MsMainContainer'),
MsAsideContainer: () => import('metersphere-frontend/src/components/MsAsideContainer'),
MsContainer: () => import('metersphere-frontend/src/components/MsContainer'),
MsEditApiScenario: () => import('./scenario/EditApiScenario'),
},
comments: {},
@ -274,8 +220,7 @@ export default {
}
},
activeName() {
this.isAsideHidden =
this.activeName === 'default' || this.activeName === 'trash';
this.isAsideHidden = this.activeName === 'default' || this.activeName === 'trash';
},
},
methods: {
@ -329,10 +274,7 @@ export default {
getModuleByProjectId(projectId).then((response) => {
if (response.data) {
response.data.forEach((node) => {
node.name =
node.name === '未规划场景'
? this.$t('api_test.automation.unplanned_scenario')
: node.name;
node.name = node.name === '未规划场景' ? this.$t('api_test.automation.unplanned_scenario') : node.name;
buildTree(node, { path: '' });
});
this.moduleOptions = response.data;
@ -525,10 +467,7 @@ export default {
if (v3.scenarioDefinition) {
this.deleteResourceIds(v3.scenarioDefinition);
}
let delta = jsondiffpatch.diff(
JSON.parse(JSON.stringify(v1)),
JSON.parse(JSON.stringify(v3))
);
let delta = jsondiffpatch.diff(JSON.parse(JSON.stringify(v1)), JSON.parse(JSON.stringify(v3)));
if (delta) {
this.isSave = true;
}
@ -618,8 +557,7 @@ export default {
}
if (
item.body &&
((item.body.binary && item.body.binary.length === 0) ||
(item.body.kvs && item.body.kvs.length === 0))
((item.body.binary && item.body.binary.length === 0) || (item.body.kvs && item.body.kvs.length === 0))
) {
delete item.body;
}
@ -647,26 +585,18 @@ export default {
}
});
if (message !== '') {
this.$alert(
this.$t('commons.scenario') +
' [ ' +
message +
' ] ' +
this.$t('commons.confirm_info'),
'',
{
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
callback: (action) => {
if (action === 'confirm') {
this.removeTab(targetName);
this.isSave = false;
} else {
this.isSave = false;
}
},
}
);
this.$alert(this.$t('commons.scenario') + ' [ ' + message + ' ] ' + this.$t('commons.confirm_info'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
callback: (action) => {
if (action === 'confirm') {
this.removeTab(targetName);
this.isSave = false;
} else {
this.isSave = false;
}
},
});
} else {
this.isSave = false;
this.removeTab(targetName);
@ -681,12 +611,7 @@ export default {
if (index !== -1) {
// vuex
let tab = this.tabs[index];
if (
tab &&
tab.currentScenario &&
store.scenarioEnvMap &&
store.scenarioEnvMap instanceof Map
) {
if (tab && tab.currentScenario && store.scenarioEnvMap && store.scenarioEnvMap instanceof Map) {
store.scenarioEnvMap.forEach((v, k) => {
if (k.indexOf(tab.currentScenario.id) !== -1) {
store.scenarioEnvMap.delete(k);
@ -764,10 +689,7 @@ export default {
this.$error(this.$t('api_test.scenario_jump_message'));
return;
}
const index = this.tabs.find(
(p) =>
p.currentScenario.id === row.id && p.currentScenario.copy === row.copy
);
const index = this.tabs.find((p) => p.currentScenario.id === row.id && p.currentScenario.copy === row.copy);
if (!index) {
this.addTab({ name: 'edit', currentScenario: row });
} else {
@ -806,13 +728,11 @@ export default {
});
},
getProject() {
getProjectConfig(this.projectId, '/SCENARIO_CUSTOM_NUM').then(
(result) => {
if (result.data) {
this.customNum = result.data.scenarioCustomNum;
}
getProjectConfig(this.projectId, '/SCENARIO_CUSTOM_NUM').then((result) => {
if (result.data) {
this.customNum = result.data.scenarioCustomNum;
}
);
});
},
updateInitApiTableOpretion(param) {
this.initApiTableOpretion = param;
@ -822,8 +742,7 @@ export default {
this.$refs.apiScenarioList.condition.versionId = currentVersion || null;
}
if (this.$refs.apiTrashScenarioList) {
this.$refs.apiTrashScenarioList.condition.versionId =
currentVersion || null;
this.$refs.apiTrashScenarioList.condition.versionId = currentVersion || null;
}
this.refreshAll();
},

View File

@ -76,13 +76,7 @@ function getScenarioFiles(obj) {
return scenarioFiles;
}
export function saveScenario(
url,
scenario,
scenarioDefinition,
_this,
success
) {
export function saveScenario(url, scenario, scenarioDefinition, _this, success) {
let bodyFiles = getBodyUploadFiles(scenario, scenarioDefinition);
if (store.pluginFiles && store.pluginFiles.length > 0) {
store.pluginFiles.forEach((fileItem) => {
@ -104,10 +98,7 @@ export function saveScenario(
formData.append('scenarioFiles', f);
});
}
formData.append(
'request',
new Blob([JSON.stringify(scenario)], { type: 'application/json' })
);
formData.append('request', new Blob([JSON.stringify(scenario)], { type: 'application/json' }));
let config = getUploadConfig(url, formData);
editScenario(config).then(
(response) => {
@ -155,29 +146,14 @@ export function scenarioSort(_this) {
_this.scenarioDefinition[i].projectId = _this.projectId;
}
if (
_this.scenarioDefinition[i].hashTree != undefined &&
_this.scenarioDefinition[i].hashTree.length > 0
) {
if (_this.scenarioDefinition[i].hashTree != undefined && _this.scenarioDefinition[i].hashTree.length > 0) {
if (_this.hideTreeNode) {
_this.hideTreeNode(
_this.scenarioDefinition[i],
_this.scenarioDefinition[i].hashTree
);
_this.hideTreeNode(_this.scenarioDefinition[i], _this.scenarioDefinition[i].hashTree);
}
recursiveSorting(
_this,
_this.scenarioDefinition[i].hashTree,
_this.scenarioDefinition[i].projectId
);
recursiveSorting(_this, _this.scenarioDefinition[i].hashTree, _this.scenarioDefinition[i].projectId);
}
// 添加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
);
@ -197,9 +173,7 @@ export function recursiveSorting(_this, arr, scenarioProjectId) {
arr[i].countController.proceed = true;
}
if (!arr[i].projectId) {
arr[i].projectId = scenarioProjectId
? scenarioProjectId
: _this.projectId;
arr[i].projectId = scenarioProjectId ? scenarioProjectId : _this.projectId;
}
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
if (_this.hideTreeNode) {

View File

@ -14,23 +14,14 @@
:report="report"
:project-env-map="projectEnvMap"
@reportExport="handleExport"
@reportSave="handleSave"
/>
@reportSave="handleSave" />
<!-- content -->
<main v-if="isNotRunning">
<!-- content header chart -->
<ms-metric-chart
:content="content"
:totalTime="totalTime"
:report="report"
/>
<ms-metric-chart :content="content" :totalTime="totalTime" :report="report" />
<el-tabs
v-model="activeName"
@tab-click="handleClick"
style="min-width: 1200px"
>
<el-tabs v-model="activeName" @tab-click="handleClick" style="min-width: 1200px">
<!-- all step-->
<el-tab-pane label="All" name="total">
<ms-scenario-results
@ -40,8 +31,7 @@
:is-share="isShare"
:share-id="shareId"
v-on:requestResult="requestResult"
ref="resultsTree"
/>
ref="resultsTree" />
</el-tab-pane>
<!-- fail step -->
<el-tab-pane name="fail">
@ -54,8 +44,7 @@
:share-id="shareId"
:treeData="fullTreeNodes"
ref="failsTree"
:errorReport="content.error"
/>
:errorReport="content.error" />
</el-tab-pane>
<!--error step -->
<el-tab-pane name="errorReport" v-if="content.errorCode > 0">
@ -69,8 +58,7 @@
:share-id="shareId"
:console="content.console"
:treeData="fullTreeNodes"
ref="errorReportTree"
/>
ref="errorReportTree" />
</el-tab-pane>
<!-- Not performed step -->
<el-tab-pane name="unExecute" v-if="content.unExecute > 0">
@ -84,8 +72,7 @@
:share-id="shareId"
:console="content.console"
:treeData="fullTreeNodes"
ref="unExecuteTree"
/>
ref="unExecuteTree" />
</el-tab-pane>
<!-- console -->
<el-tab-pane name="console">
@ -96,8 +83,7 @@
:mode="'text'"
:read-only="true"
:data.sync="content.console"
height="calc(100vh - 500px)"
/>
height="calc(100vh - 500px)" />
</el-tab-pane>
</el-tabs>
</main>
@ -114,8 +100,7 @@
:title="report.name"
:content="content"
:report="report"
:total-time="totalTime"
/>
:total-time="totalTime" />
</div>
</template>
@ -243,12 +228,7 @@ export default {
}
},
rerunVerify() {
if (
hasLicense() &&
this.fullTreeNodes &&
this.fullTreeNodes.length > 0 &&
!this.isShare
) {
if (hasLicense() && this.fullTreeNodes && this.fullTreeNodes.length > 0 && !this.isShare) {
this.fullTreeNodes.forEach((item) => {
item.redirect = true;
if (
@ -264,11 +244,7 @@ export default {
},
handleClick(tab, event) {
this.isRequestResult = false;
if (
this.report &&
this.report.reportVersion &&
this.report.reportVersion > 1
) {
if (this.report && this.report.reportVersion && this.report.reportVersion > 1) {
this.filter(tab.index);
}
},
@ -324,9 +300,7 @@ export default {
node.children = [];
} else {
if (item.subRequestResults && item.subRequestResults.length > 0) {
let itemChildren = this.deepFormatTreeNode(
item.subRequestResults
);
let itemChildren = this.deepFormatTreeNode(item.subRequestResults);
node.children = itemChildren;
if (node.label.indexOf('UUID=')) {
node.label = node.label.split('UUID=')[0];
@ -370,8 +344,7 @@ export default {
if (i !== nodeArray.length - 1 && !children[j].children) {
children[j].children = [];
}
children =
i === nodeArray.length - 1 ? children : children[j].children;
children = i === nodeArray.length - 1 ? children : children[j].children;
isExist = true;
break;
}
@ -379,16 +352,10 @@ export default {
}
if (!isExist) {
children.push(node);
if (
i !== nodeArray.length - 1 &&
!children[children.length - 1].children
) {
if (i !== nodeArray.length - 1 && !children[children.length - 1].children) {
children[children.length - 1].children = [];
}
children =
i === nodeArray.length - 1
? children
: children[children.length - 1].children;
children = i === nodeArray.length - 1 ? children : children[children.length - 1].children;
}
}
});
@ -444,10 +411,7 @@ export default {
//
if (scenarioDefinition[i]) {
scenarioDefinition[i].index = Number(i) + 1;
if (
scenarioDefinition[i].children &&
scenarioDefinition[i].children.length > 0
) {
if (scenarioDefinition[i].children && scenarioDefinition[i].children.length > 0) {
this.recursiveSorting(scenarioDefinition[i].children);
}
}
@ -468,8 +432,7 @@ export default {
this.fullTreeNodes = report.steps;
this.content.console = report.console;
this.content.error = report.error;
let successCount =
report.total - report.error - report.errorCode - report.unExecute;
let successCount = report.total - report.error - report.errorCode - report.unExecute;
this.content.success = successCount;
this.totalTime = report.totalTime;
}
@ -529,18 +492,13 @@ export default {
this.fullTreeNodes = report.steps;
this.content.console = report.console;
this.content.error = report.error;
let successCount =
report.total -
report.error -
report.errorCode -
report.unExecute;
let successCount = report.total - report.error - report.errorCode - report.unExecute;
this.content.success = successCount;
this.totalTime = report.totalTime;
}
//
if (
(this.report &&
this.report.reportType === 'SCENARIO_INTEGRATED') ||
(this.report && this.report.reportType === 'SCENARIO_INTEGRATED') ||
this.report.reportType === 'API_INTEGRATED'
) {
this.rerunVerify();
@ -579,11 +537,7 @@ export default {
let tempMap = new Map();
for (let i = 0; i < children.length; i++) {
if (
!children[i].value ||
!children[i].value.startTime ||
children[i].value.startTime === 0
) {
if (!children[i].value || !children[i].value.startTime || children[i].value.startTime === 0) {
//valuestep
tempArr[i] = children[i];
//
@ -702,10 +656,7 @@ export default {
},
formatExportApi(array, scenario) {
array.forEach((item) => {
if (
this.stepFilter &&
this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1
) {
if (this.stepFilter && this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1) {
if (item.errorCode) {
item.value.errorCode = item.errorCode;
}
@ -721,10 +672,7 @@ export default {
},
startExport() {
if (this.report.reportVersion && this.report.reportVersion > 1) {
if (
this.report.reportType === 'API_INTEGRATED' ||
this.report.reportType === 'UI_INTEGRATED'
) {
if (this.report.reportType === 'API_INTEGRATED' || this.report.reportType === 'UI_INTEGRATED') {
let scenario = { name: '', requestResults: [] };
this.content.scenarios = [scenario];
this.formatExportApi(this.fullTreeNodes, scenario);
@ -733,10 +681,7 @@ export default {
this.fullTreeNodes.forEach((item) => {
if (item.type === 'scenario') {
let scenario = { name: item.label, requestResults: [] };
if (
this.content.scenarios &&
this.content.scenarios.length > 0
) {
if (this.content.scenarios && this.content.scenarios.length > 0) {
this.content.scenarios.push(scenario);
} else {
this.content.scenarios = [scenario];
@ -752,10 +697,7 @@ export default {
let name = this.report.name;
this.$nextTick(() => {
setTimeout(() => {
downloadPDF(
document.getElementById('apiTestReport'),
name || 'scenario-report'
);
downloadPDF(document.getElementById('apiTestReport'), name || 'scenario-report');
reset();
}, 5000);
});

View File

@ -3,30 +3,16 @@
:title="title"
:report="report"
:project-env-map="projectEnvMap"
:type="$t('report.api_test_report')"
>
<ms-metric-chart
:content="content"
:is-export="true"
:totalTime="totalTime"
:report="report"
/>
<div
class="scenario-result"
v-for="(scenario, index) in content.scenarios"
:key="index"
:scenario="scenario"
>
:type="$t('report.api_test_report')">
<ms-metric-chart :content="content" :is-export="true" :totalTime="totalTime" :report="report" />
<div class="scenario-result" v-for="(scenario, index) in content.scenarios" :key="index" :scenario="scenario">
<el-card>
<template v-slot:header>
{{ $t('api_report.scenario_name') }}{{ scenario.name }}
</template>
<template v-slot:header> {{ $t('api_report.scenario_name') }}{{ scenario.name }} </template>
<div
class="ms-border clearfix"
v-for="(request, index) in scenario.requestResults"
:key="index"
:request="request"
>
:request="request">
<div class="request-top">
<div>
{{ getName(request.name) }}
@ -37,15 +23,11 @@
</div>
<el-divider />
<div class="request-middle">
<api-report-request-header-item
:title="$t('api_test.request.method')"
>
<api-report-request-header-item :title="$t('api_test.request.method')">
<span class="method"> {{ request.method }}</span>
</api-report-request-header-item>
<api-report-request-header-item
:title="$t('api_report.response_time')"
>
<api-report-request-header-item :title="$t('api_report.response_time')">
{{ request.responseResult.responseTime }} ms
</api-report-request-header-item>
@ -53,15 +35,11 @@
{{ request.responseResult.latency }} ms
</api-report-request-header-item>
<api-report-request-header-item
:title="$t('api_report.request_size')"
>
<api-report-request-header-item :title="$t('api_report.request_size')">
{{ request.requestSize }} bytes
</api-report-request-header-item>
<api-report-request-header-item
:title="$t('api_report.response_size')"
>
<api-report-request-header-item :title="$t('api_report.response_size')">
{{ request.responseResult.responseSize }} bytes
</api-report-request-header-item>
@ -69,36 +47,23 @@
{{ request.error }}
</api-report-request-header-item>
<api-report-request-header-item
:title="$t('api_report.assertions')"
>
<api-report-request-header-item :title="$t('api_report.assertions')">
{{ request.passAssertions + ' / ' + request.totalAssertions }}
</api-report-request-header-item>
<api-report-request-header-item
:title="$t('api_report.response_code')"
>
<api-report-request-header-item :title="$t('api_report.response_code')">
{{ request.responseResult.responseCode }}
</api-report-request-header-item>
<api-report-request-header-item :title="$t('api_report.result')">
<el-tag v-if="request.unexecute"
>{{ $t('api_test.home_page.detail_card.unexecute') }}
</el-tag>
<el-tag
v-else-if="
!request.success &&
request.status &&
request.status === 'PENDING'
"
<el-tag v-if="request.unexecute">{{ $t('api_test.home_page.detail_card.unexecute') }} </el-tag>
<el-tag v-else-if="!request.success && request.status && request.status === 'PENDING'"
>{{ $t('api_test.home_page.detail_card.unexecute') }}
</el-tag>
<el-tag v-else-if="request.errorCode" class="ms-test-error_code">
{{ $t('error_report_library.option.name') }}
</el-tag>
<el-tag size="mini" type="success" v-else-if="request.success">
Success
</el-tag>
<el-tag size="mini" type="success" v-else-if="request.success"> Success </el-tag>
<el-tag size="mini" type="danger" v-else> Error </el-tag>
</api-report-request-header-item>
</div>

View File

@ -3,42 +3,17 @@
<ms-main-container>
<el-card class="table-card" v-loading="result">
<template v-slot:header>
<ms-table-header
:condition.sync="condition"
v-if="loadIsOver"
@search="search"
:show-create="false"
>
<ms-table-header :condition.sync="condition" v-if="loadIsOver" @search="search" :show-create="false">
<template v-slot:button>
<el-button-group>
<el-tooltip
class="item"
effect="dark"
content="left"
:disabled="true"
placement="left"
>
<el-button
plain
:class="{ active: leftActive }"
@click="changeTab('left')"
>
<el-tooltip class="item" effect="dark" content="left" :disabled="true" placement="left">
<el-button plain :class="{ active: leftActive }" @click="changeTab('left')">
{{ $t('commons.scenario') }}
</el-button>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="right"
:disabled="true"
placement="right"
>
<el-button
plain
:class="{ active: rightActive }"
@click="changeTab('right')"
>
<el-tooltip class="item" effect="dark" content="right" :disabled="true" placement="right">
<el-button plain :class="{ active: rightActive }" @click="changeTab('right')">
{{ $t('api_test.definition.request.case') }}
</el-button>
</el-tooltip>
@ -58,36 +33,24 @@
:height="screenHeight"
@filter-change="filter"
@row-click="handleView"
v-if="loadIsOver"
>
v-if="loadIsOver">
<el-table-column type="selection" />
<el-table-column width="40" :resizable="false" align="center">
<el-dropdown slot="header" style="width: 14px">
<span class="el-dropdown-link" style="width: 14px">
<i
class="el-icon-arrow-down el-icon--right"
style="margin-left: 0px"
></i>
<i class="el-icon-arrow-down el-icon--right" style="margin-left: 0px"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native.stop="isSelectDataAll(true)">
{{ $t('api_test.batch_menus.select_all_data', [total]) }}
</el-dropdown-item>
<el-dropdown-item @click.native.stop="isSelectDataAll(false)">
{{
$t('api_test.batch_menus.select_show_data', [
tableData.length,
])
}}
{{ $t('api_test.batch_menus.select_show_data', [tableData.length]) }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<template v-slot:default="scope">
<show-more-btn
:is-show="scope.row.showMore"
:buttons="buttons"
:size="selectDataCounts"
/>
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectDataCounts" />
</template>
</el-table-column>
@ -99,8 +62,7 @@
:editable="true"
:edit-content="$t('report.rename_report')"
@editColumn="openReNameDialog"
min-width="200px"
>
min-width="200px">
</ms-table-column>
<el-table-column
@ -108,8 +70,7 @@
:label="$t('load_test.report_type')"
width="150"
column-key="reportType"
:filters="reportTypeFilters"
>
:filters="reportTypeFilters">
<template v-slot:default="scope">
<div v-if="scope.row.reportType === 'SCENARIO_INTEGRATED'">
<el-tag size="mini" type="primary">
@ -142,24 +103,13 @@
:label="$t('api_test.creator')"
width="150"
show-overflow-tooltip
:filters="userFilters"
/>
<el-table-column
prop="createTime"
min-width="120"
:label="$t('commons.create_time')"
sortable
>
:filters="userFilters" />
<el-table-column prop="createTime" min-width="120" :label="$t('commons.create_time')" sortable>
<template v-slot:default="scope">
<span>{{ scope.row.createTime | datetimeFormat }}</span>
</template>
</el-table-column>
<el-table-column
prop="endTime"
min-width="120"
:label="$t('report.test_end_time')"
sortable
>
<el-table-column prop="endTime" min-width="120" :label="$t('report.test_end_time')" sortable>
<template v-slot:default="scope">
<span v-if="scope.row.endTime && scope.row.endTime > 0">
{{ scope.row.endTime | datetimeFormat }}
@ -174,18 +124,12 @@
width="150"
:label="$t('commons.trigger_mode.name')"
column-key="triggerMode"
:filters="triggerFilters"
>
:filters="triggerFilters">
<template v-slot:default="scope">
<report-trigger-mode-item :trigger-mode="scope.row.triggerMode" />
</template>
</el-table-column>
<el-table-column
:label="$t('commons.status')"
:filters="statusFilters"
column-key="status"
prop="status"
>
<el-table-column :label="$t('commons.status')" :filters="statusFilters" column-key="status" prop="status">
<template v-slot:default="{ row }">
<ms-api-report-status :status="row.status" />
</template>
@ -197,15 +141,13 @@
:tip="$t('api_report.detail')"
icon="el-icon-s-data"
@exec="handleView(scope.row)"
type="primary"
/>
type="primary" />
<ms-table-operator-button
:tip="$t('api_report.delete')"
v-permission="['PROJECT_API_REPORT:READ+DELETE']"
icon="el-icon-delete"
@exec="handleDelete(scope.row)"
type="danger"
/>
type="danger" />
</div>
</template>
</el-table-column>
@ -214,13 +156,9 @@
:change="search"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:total="total"
/>
:total="total" />
</el-card>
<ms-rename-report-dialog
ref="renameDialog"
@submit="rename($event)"
></ms-rename-report-dialog>
<ms-rename-report-dialog ref="renameDialog" @submit="rename($event)"></ms-rename-report-dialog>
<el-dialog
:close-on-click-modal="false"
:title="$t('test_track.plan_view.test_result')"
@ -228,55 +166,34 @@
:visible.sync="resVisible"
class="api-import"
destroy-on-close
@close="resVisible = false"
>
<ms-request-result-tail
:report-id="reportId"
:response="response"
ref="debugResult"
/>
@close="resVisible = false">
<ms-request-result-tail :report-id="reportId" :response="response" ref="debugResult" />
</el-dialog>
</ms-main-container>
</ms-container>
</template>
<script>
import { getCurrentProjectID } from 'metersphere-frontend/src/utils/token';
import {
REPORT_CASE_CONFIGS,
REPORT_CONFIGS,
} from 'metersphere-frontend/src/components/search/search-components';
import { REPORT_CASE_CONFIGS, REPORT_CONFIGS } from 'metersphere-frontend/src/components/search/search-components';
import { _filter, _sort } from 'metersphere-frontend/src/utils/tableUtils';
import MsRenameReportDialog from 'metersphere-frontend/src/components/report/MsRenameReportDialog';
import MsTableColumn from 'metersphere-frontend/src/components/table/MsTableColumn';
import MsRequestResultTail from '@/business/definition/components/response/RequestResultTail';
import MsTabButton from '@/business/commons/MsTabs';
import { getMaintainer } from '@/api/project';
import {
delBatchReport,
delReport,
getReportPage,
reportReName,
} from '@/api/scenario-report';
import { delBatchReport, delReport, getReportPage, reportReName } from '@/api/scenario-report';
import { getApiReportPage } from '@/api/definition-report';
import { REPORT_STATUS } from '@/business/commons/js/commons';
export default {
components: {
ReportTriggerModeItem: () =>
import(
'metersphere-frontend/src/components/tableItem/ReportTriggerModeItem'
),
MsTableOperatorButton: () =>
import('metersphere-frontend/src/components/MsTableOperatorButton'),
ReportTriggerModeItem: () => import('metersphere-frontend/src/components/tableItem/ReportTriggerModeItem'),
MsTableOperatorButton: () => import('metersphere-frontend/src/components/MsTableOperatorButton'),
MsApiReportStatus: () => import('./ApiReportStatus'),
MsMainContainer: () =>
import('metersphere-frontend/src/components/MsMainContainer'),
MsContainer: () =>
import('metersphere-frontend/src/components/MsContainer'),
MsTableHeader: () =>
import('metersphere-frontend/src/components/MsTableHeader'),
MsTablePagination: () =>
import('metersphere-frontend/src/components/pagination/TablePagination'),
MsMainContainer: () => import('metersphere-frontend/src/components/MsMainContainer'),
MsContainer: () => import('metersphere-frontend/src/components/MsContainer'),
MsTableHeader: () => import('metersphere-frontend/src/components/MsTableHeader'),
MsTablePagination: () => import('metersphere-frontend/src/components/pagination/TablePagination'),
ShowMoreBtn: () => import('@/business/commons/ShowMoreBtn'),
MsRenameReportDialog,
MsTableColumn,
@ -308,15 +225,11 @@ export default {
reportTypeFilters: [],
reportScenarioFilters: [
{
text:
this.$t('api_test.scenario.independent') +
this.$t('commons.scenario'),
text: this.$t('api_test.scenario.independent') + this.$t('commons.scenario'),
value: 'SCENARIO_INDEPENDENT',
},
{
text:
this.$t('api_test.scenario.integrated') +
this.$t('commons.scenario'),
text: this.$t('api_test.scenario.integrated') + this.$t('commons.scenario'),
value: 'SCENARIO_INTEGRATED',
},
],
@ -398,20 +311,12 @@ export default {
this.genRedirectParams(this.condition);
if (this.activeDom === 'left') {
this.reportTypeFilters = this.reportScenarioFilters;
this.result = getReportPage(
this.currentPage,
this.pageSize,
this.condition
).then((res) => {
this.result = getReportPage(this.currentPage, this.pageSize, this.condition).then((res) => {
this.setData(res);
});
} else {
this.reportTypeFilters = this.reportCaseFilters;
this.result = getApiReportPage(
this.currentPage,
this.pageSize,
this.condition
).then((res) => {
this.result = getApiReportPage(this.currentPage, this.pageSize, this.condition).then((res) => {
this.setData(res);
});
}
@ -456,10 +361,7 @@ export default {
this.$warning(this.$t('commons.run_warning'));
return;
}
if (
report.reportType.indexOf('SCENARIO') !== -1 ||
report.reportType === 'API_INTEGRATED'
) {
if (report.reportType.indexOf('SCENARIO') !== -1 || report.reportType === 'API_INTEGRATED') {
this.currentProjectId = report.projectId;
this.$router.push({
path: 'report/view/' + report.id,
@ -470,21 +372,17 @@ export default {
}
},
handleDelete(report) {
this.$alert(
this.$t('api_report.delete_confirm') + report.name + '',
'',
{
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
delReport(report.id).then(() => {
this.$success(this.$t('commons.delete_success'));
this.search();
});
}
},
}
);
this.$alert(this.$t('api_report.delete_confirm') + report.name + '', '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
delReport(report.id).then(() => {
this.$success(this.$t('commons.delete_success'));
this.search();
});
}
},
});
},
init() {
this.testId = this.$route.params.testId;
@ -533,8 +431,7 @@ export default {
sendParam.selectAllDate = this.isSelectAllDate;
sendParam.unSelectIds = this.unSelection;
sendParam = Object.assign(sendParam, this.condition);
sendParam.caseType =
this.activeDom === 'right' ? 'API' : 'SCENARIO';
sendParam.caseType = this.activeDom === 'right' ? 'API' : 'SCENARIO';
delBatchReport(sendParam).then(() => {
this.selectRows.clear();
this.$success(this.$t('commons.delete_success'));

View File

@ -1,18 +1,9 @@
<template>
<div>
<el-tag
size="mini"
type="primary"
effect="plain"
v-if="getStatus(status) === 'running'"
>
<el-tag size="mini" type="primary" effect="plain" v-if="getStatus(status) === 'running'">
{{ showStatus(status) }}
</el-tag>
<el-tag
size="mini"
type="success"
v-else-if="getStatus(status) === 'success'"
>
<el-tag size="mini" type="success" v-else-if="getStatus(status) === 'success'">
{{ showStatus(status) }}
</el-tag>
<el-tag size="mini" type="danger" v-else-if="getStatus(status) === 'error'">
@ -22,8 +13,7 @@
size="mini"
type="danger"
style="background-color: #f6972a; color: #ffffff"
v-else-if="getStatus(status) === 'fake_error'"
>
v-else-if="getStatus(status) === 'fake_error'">
FakeError
</el-tag>
<span v-else-if="status === '-'" size="mini" type="info"> - </span>
@ -51,9 +41,7 @@ export default {
if (!status) {
status = 'PENDING';
}
return (
status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1)
);
return status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1);
},
},
};

View File

@ -5,8 +5,7 @@
:is-share="isShare"
:is-plan="isPlanReport"
:template-report="response"
:is-template="isTemplate"
/>
:is-template="isTemplate" />
</template>
<script>

View File

@ -11,15 +11,9 @@
style="width: 200px"
v-model="report.name"
maxlength="60"
show-word-limit
/>
show-word-limit />
<span v-else>
<el-link
v-if="isSingleScenario"
type="primary"
class="report-name"
@click="redirect"
>
<el-link v-if="isSingleScenario" type="primary" class="report-name" @click="redirect">
{{ report.name }}
</el-link>
<span v-else>
@ -30,18 +24,13 @@
class="el-icon-edit"
style="cursor: pointer"
@click="nameIsEdit = true"
@click.stop
/>
@click.stop />
</span>
</span>
<span v-if="report.endTime || report.createTime">
<span style="margin-left: 10px"
>{{ $t('report.test_start_time') }}</span
>
<span style="margin-left: 10px">{{ $t('report.test_start_time') }}</span>
<span class="time"> {{ report.createTime | datetimeFormat }}</span>
<span style="margin-left: 10px"
>{{ $t('report.test_end_time') }}</span
>
<span style="margin-left: 10px">{{ $t('report.test_end_time') }}</span>
<span class="time"> {{ report.endTime | datetimeFormat }}</span>
</span>
<div style="float: right">
@ -54,8 +43,7 @@
type="primary"
size="mini"
@click="handleExport(report.name)"
style="margin-right: 10px"
>
style="margin-right: 10px">
{{ $t('test_track.plan_view.export_report') }}
</el-button>
@ -65,53 +53,28 @@
style="margin-right: 10px; float: right"
placement="bottom"
trigger="click"
width="300"
>
width="300">
<p>{{ shareUrl }}</p>
<span
style="color: red; float: left; margin-left: 10px"
v-if="application.typeValue"
>{{ $t('commons.validity_period') + application.typeValue }}</span
>
<span style="color: red; float: left; margin-left: 10px" v-if="application.typeValue">{{
$t('commons.validity_period') + application.typeValue
}}</span>
<div style="text-align: right; margin: 0">
<el-button
type="primary"
size="mini"
:disabled="!shareUrl"
v-clipboard:copy="shareUrl"
<el-button type="primary" size="mini" :disabled="!shareUrl" v-clipboard:copy="shareUrl"
>{{ $t('commons.copy') }}
</el-button>
</div>
<template v-slot:reference>
<el-button
:disabled="isReadOnly"
type="danger"
plain
size="mini"
@click="handleShare(report)"
>
<el-button :disabled="isReadOnly" type="danger" plain size="mini" @click="handleShare(report)">
{{ $t('test_track.plan_view.share_report') }}
</el-button>
</template>
</el-popover>
<el-button
v-if="showRerunButton"
class="rerun-button"
plain
size="mini"
@click="rerun"
>
<el-button v-if="showRerunButton" class="rerun-button" plain size="mini" @click="rerun">
{{ $t('api_test.automation.rerun') }}
</el-button>
<el-button
v-if="showCancelButton"
class="export-button"
plain
size="mini"
@click="returnView"
>
<el-button v-if="showCancelButton" class="export-button" plain size="mini" @click="returnView">
{{ $t('commons.cancel') }}
</el-button>
</div>
@ -119,33 +82,17 @@
</el-row>
<el-row v-if="showProjectEnv" type="flex">
<span> {{ $t('commons.environment') + ':' }} </span>
<div
v-for="(values, key) in projectEnvMap"
:key="key"
style="margin-right: 10px"
>
<div v-for="(values, key) in projectEnvMap" :key="key" style="margin-right: 10px">
{{ key + ':' }}
<ms-tag
v-for="(item, index) in values"
:key="index"
type="success"
:content="item"
style="margin-left: 2px"
/>
<ms-tag v-for="(item, index) in values" :key="index" type="success" :content="item" style="margin-left: 2px" />
</div>
</el-row>
</header>
</template>
<script>
import {
generateShareInfoWithExpired,
getShareRedirectUrl,
} from '../../../api/share';
import {
getCurrentProjectID,
getCurrentWorkspaceId,
} from 'metersphere-frontend/src/utils/token';
import { generateShareInfoWithExpired, getShareRedirectUrl } from '../../../api/share';
import { getCurrentProjectID, getCurrentWorkspaceId } from 'metersphere-frontend/src/utils/token';
import MsTag from 'metersphere-frontend/src/components/MsTag';
import { getProjectApplicationConfig } from '../../../api/project';
import { apiTestReRun } from '../../../api/xpack';
@ -270,27 +217,16 @@ export default {
});
},
getProjectApplication() {
getProjectApplicationConfig(
getCurrentProjectID(),
'/API_SHARE_REPORT_TIME'
).then((res) => {
getProjectApplicationConfig(getCurrentProjectID(), '/API_SHARE_REPORT_TIME').then((res) => {
if (res.data && res.data.typeValue) {
let quantity = res.data.typeValue.substring(
0,
res.data.typeValue.length - 1
);
let unit = res.data.typeValue.substring(
res.data.typeValue.length - 1
);
let quantity = res.data.typeValue.substring(0, res.data.typeValue.length - 1);
let unit = res.data.typeValue.substring(res.data.typeValue.length - 1);
if (unit === 'H') {
res.data.typeValue = quantity + this.$t('commons.date_unit.hour');
} else if (unit === 'D') {
res.data.typeValue = quantity + this.$t('commons.date_unit.day');
} else if (unit === 'M') {
res.data.typeValue =
quantity +
this.$t('commons.workspace_unit') +
this.$t('commons.date_unit.month');
res.data.typeValue = quantity + this.$t('commons.workspace_unit') + this.$t('commons.date_unit.month');
} else if (unit === 'Y') {
res.data.typeValue = quantity + this.$t('commons.date_unit.year');
}

View File

@ -11,16 +11,10 @@
:report="report"
:project-env-map="projectEnvMap"
@reportExport="handleExport"
@reportSave="handleSave"
/>
@reportSave="handleSave" />
</div>
<main>
<ms-metric-chart
:content="content"
:totalTime="totalTime"
:report="report"
v-if="!loading"
/>
<ms-metric-chart :content="content" :totalTime="totalTime" :report="report" v-if="!loading" />
<div>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="All" name="total">
@ -29,8 +23,7 @@
:report="report"
:default-expand="true"
:console="content.console"
v-on:requestResult="requestResult"
/>
v-on:requestResult="requestResult" />
</el-tab-pane>
<el-tab-pane name="fail">
<template slot="label"> Error </template>
@ -39,8 +32,7 @@
:report="report"
:treeData="fullTreeNodes"
v-on:requestResult="requestResult"
ref="failsTree"
/>
ref="failsTree" />
</el-tab-pane>
<el-tab-pane name="errorReport" v-if="content.errorCode > 0">
<template slot="label">
@ -50,8 +42,7 @@
v-on:requestResult="requestResult"
:console="content.console"
:treeData="fullTreeNodes"
ref="errorReportTree"
/>
ref="errorReportTree" />
</el-tab-pane>
<el-tab-pane name="unExecute" v-if="content.unExecute > 0">
<template slot="label">
@ -62,8 +53,7 @@
:report="report"
:console="content.console"
:treeData="fullTreeNodes"
ref="unExecuteTree"
/>
ref="unExecuteTree" />
</el-tab-pane>
<el-tab-pane name="console">
<template slot="label">
@ -79,8 +69,7 @@
:total-time="totalTime"
:project-env-map="projectEnvMap"
id="apiTestReport"
v-if="reportExportVisible"
/>
v-if="reportExportVisible" />
</main>
</section>
</el-card>
@ -151,8 +140,7 @@ export default {
mounted() {
this.$nextTick(() => {
if (this.scenario && this.scenario.scenarioDefinition) {
this.content.scenarioStepTotal =
this.scenario.scenarioDefinition.hashTree.length;
this.content.scenarioStepTotal = this.scenario.scenarioDefinition.hashTree.length;
this.initTree();
this.initMessageSocket();
this.clearDebug();
@ -186,12 +174,7 @@ export default {
children: [],
unsolicited: true,
};
this.formatContent(
this.scenario.scenarioDefinition.hashTree,
obj,
'',
'root'
);
this.formatContent(this.scenario.scenarioDefinition.hashTree, obj, '', 'root');
this.fullTreeNodes.push(obj);
},
compare() {
@ -230,14 +213,9 @@ export default {
if (hashTree) {
hashTree.forEach((item) => {
if (item.enable) {
item.parentIndex = fullPath
? fullPath + '_' + item.index
: item.index;
item.parentIndex = fullPath ? fullPath + '_' + item.index : item.index;
let name = item.name ? item.name : this.getType(item.type);
let id =
item.type === 'JSR223Processor' || !item.id
? item.resourceId
: item.id;
let id = item.type === 'JSR223Processor' || !item.id ? item.resourceId : item.id;
let obj = {
pid: pid,
resId: id + '_' + item.parentIndex,
@ -254,9 +232,7 @@ export default {
unsolicited: true,
};
tree.children.push(obj);
if (
this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1
) {
if (this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1) {
obj.unsolicited = false;
obj.type = item.type;
} else if (item.type === 'scenario') {
@ -268,12 +244,7 @@ export default {
this.stepFilter &&
this.stepFilter.get('AllSamplerProxy').indexOf(item.type) === -1
) {
this.formatContent(
item.hashTree,
obj,
item.parentIndex,
obj.resId
);
this.formatContent(item.hashTree, obj, item.parentIndex, obj.resId);
}
}
});
@ -386,10 +357,7 @@ export default {
this.content.error = this.content ? this.content.error : '';
this.content.success =
this.content.total -
this.content.error -
this.content.errorCode -
this.content.unExecute;
this.content.total - this.content.error - this.content.errorCode - this.content.unExecute;
this.totalTime = this.content.totalTime;
this.fullTreeNodes = this.content.steps;
this.recursiveSorting(this.fullTreeNodes);
@ -424,11 +392,7 @@ export default {
let tempMap = new Map();
for (let i = 0; i < children.length; i++) {
if (
!children[i].value ||
!children[i].value.startTime ||
children[i].value.startTime === 0
) {
if (!children[i].value || !children[i].value.startTime || children[i].value.startTime === 0) {
//valuestep
tempArr[i] = children[i];
//
@ -474,11 +438,7 @@ export default {
if (!data.status && data.success) {
data.status = 'SUCCESS';
}
if (
data.method === 'Request' &&
data.subRequestResults &&
data.subRequestResults.length > 0
) {
if (data.method === 'Request' && data.subRequestResults && data.subRequestResults.length > 0) {
this.margeTransaction(item, data.subRequestResults);
} else if (item.resId === data.resourceId) {
if (item.value && item.value.id && !item.mark) {
@ -514,11 +474,7 @@ export default {
if (!data.status && data.success) {
data.status = 'SUCCESS';
}
if (
data.method === 'Request' &&
data.subRequestResults &&
data.subRequestResults.length > 0
) {
if (data.method === 'Request' && data.subRequestResults && data.subRequestResults.length > 0) {
data.subRequestResults.forEach((subItem) => {
if (item.resId === subItem.resourceId) {
item.value = subItem;

View File

@ -1,20 +1,9 @@
<template>
<div>
<el-table
:data="assertions"
:row-style="getRowStyle"
:header-cell-style="getRowStyle"
>
<el-table-column
prop="name"
:label="$t('api_report.assertions_name')"
width="150"
show-overflow-tooltip
>
<el-table :data="assertions" :row-style="getRowStyle" :header-cell-style="getRowStyle">
<el-table-column prop="name" :label="$t('api_report.assertions_name')" width="150" show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{
!scope.row.name || scope.row.name === 'null' ? '' : scope.row.name
}}</span>
<span>{{ !scope.row.name || scope.row.name === 'null' ? '' : scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column
@ -22,17 +11,9 @@
v-if="showContent"
:label="$t('api_report.assertions_content')"
width="300"
show-overflow-tooltip
/>
<el-table-column
prop="message"
:label="$t('api_report.assertions_error_message')"
/>
<el-table-column
prop="pass"
:label="$t('api_report.assertions_is_success')"
width="180"
>
show-overflow-tooltip />
<el-table-column prop="message" :label="$t('api_report.assertions_error_message')" />
<el-table-column prop="pass" :label="$t('api_report.assertions_is_success')" width="180">
<template v-slot:default="{ row }">
<el-tag size="mini" type="success" v-if="row.pass"> Success </el-tag>
<el-tag size="mini" type="danger" v-else> Error </el-tag>
@ -44,8 +25,7 @@
<i
class="el-icon-view el-button el-button--primary el-button--mini is-circle"
circle
@click="showPage(row.script)"
/>
@click="showPage(row.script)" />
</div>
</template>
</el-table-column>
@ -55,14 +35,8 @@
:visible.sync="visible"
width="900px"
modal-append-to-body
append-to-body
>
<el-row
type="flex"
justify="space-between"
align="middle"
class="quick-script-block"
>
append-to-body>
<el-row type="flex" justify="space-between" align="middle" class="quick-script-block">
<el-col :span="codeSpan" class="script-content">
<ms-code-edit
v-if="isCodeEditAlive"
@ -70,8 +44,7 @@
:data.sync="scriptContent"
theme="eclipse"
:modes="['java', 'python']"
ref="codeEdit"
/>
ref="codeEdit" />
</el-col>
</el-row>
</el-dialog>

View File

@ -16,15 +16,9 @@
(content.error && content.error > 0) ||
(content.errorCode && content.errorCode > 0) ||
(content.unExecute && content.unExecute > 0)
"
>
">
<span class="ms-req-span">
{{
content.success +
content.error +
content.errorCode +
content.unExecute
}}
{{ content.success + content.error + content.errorCode + content.unExecute }}
{{ $t('api_report.request') }}
</span>
</span>
@ -36,67 +30,35 @@
</span>
</div>
<!-- 饼图显示/成功/失败/误报 -->
<ms-chart
ref="chart"
:options="options"
:height="150"
:width="150"
:autoresize="true"
v-else
/>
<ms-chart ref="chart" :options="options" :height="150" :width="150" :autoresize="true" v-else />
<!-- 总数统计 -->
<el-row type="flex" justify="center" align="middle">
<div style="min-width: 120px">
<div class="metric-icon-box">
<span
class="ms-point-success"
style="margin: 7px; float: left"
/>
<span class="ms-point-success" style="margin: 7px; float: left" />
<div class="metric-box-total">
<div class="value" style="font-size: 12px">
{{ content.success }} Success
</div>
<div class="value" style="font-size: 12px">{{ content.success }} Success</div>
</div>
</div>
<el-divider></el-divider>
<div class="metric-icon-box" style="height: 26px">
<span class="ms-point-error" style="margin: 7px; float: left" />
<div class="metric-box-total">
<div class="value" style="font-size: 12px">
{{ content.error }} Error
</div>
<div class="value" style="font-size: 12px">{{ content.error }} Error</div>
</div>
</div>
<el-divider v-if="content.errorCode > 0"></el-divider>
<div
class="metric-icon-box"
v-if="content.errorCode > 0"
style="height: 26px"
>
<span
class="ms-point-error-code"
style="margin: 7px; float: left"
/>
<div class="metric-icon-box" v-if="content.errorCode > 0" style="height: 26px">
<span class="ms-point-error-code" style="margin: 7px; float: left" />
<div class="metric-box-total" v-if="content.errorCode > 0">
<div class="value" style="font-size: 12px">
{{ content.errorCode }} FakeError
</div>
<div class="value" style="font-size: 12px">{{ content.errorCode }} FakeError</div>
</div>
</div>
<el-divider v-if="content.unExecute > 0"></el-divider>
<div
class="metric-icon-box"
style="height: 26px"
v-if="content.unExecute > 0"
>
<span
class="ms-point-unexecute"
style="margin: 7px; float: left"
/>
<div class="metric-icon-box" style="height: 26px" v-if="content.unExecute > 0">
<span class="ms-point-unexecute" style="margin: 7px; float: left" />
<div class="metric-box-total">
<div class="value" style="font-size: 12px">
{{ content.unExecute }} Pending
</div>
<div class="value" style="font-size: 12px">{{ content.unExecute }} Pending</div>
</div>
</div>
</div>
@ -106,12 +68,7 @@
<div class="split"></div>
<!-- 场景统计 -->
<div style="width: 50%">
<el-row
type="flex"
justify="center"
align="middle"
v-if="report.reportType !== 'API_INTEGRATED'"
>
<el-row type="flex" justify="center" align="middle" v-if="report.reportType !== 'API_INTEGRATED'">
<div class="metric-box">
<div class="value">
{{ content.scenarioTotal ? content.scenarioTotal : 0 }}
@ -134,22 +91,10 @@
</div>
<span
class="ms-point-error-code"
v-if="
content.scenarioErrorReport > 0 ||
content.scenarioStepErrorReport > 0
"
/>
<div
class="metric-box"
v-if="
content.scenarioErrorReport > 0 ||
content.scenarioStepErrorReport > 0
"
>
v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0" />
<div class="metric-box" v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0">
<div class="value">
{{
content.scenarioErrorReport ? content.scenarioErrorReport : 0
}}
{{ content.scenarioErrorReport ? content.scenarioErrorReport : 0 }}
</div>
<div class="name">FakeError</div>
</div>
@ -178,9 +123,7 @@
<span class="ms-point-success" />
<div class="metric-box">
<div class="value">
{{
content.scenarioStepSuccess ? content.scenarioStepSuccess : 0
}}
{{ content.scenarioStepSuccess ? content.scenarioStepSuccess : 0 }}
</div>
<div class="name">Success</div>
</div>
@ -193,33 +136,17 @@
</div>
<span
class="ms-point-error-code"
v-if="
content.scenarioErrorReport > 0 ||
content.scenarioStepErrorReport > 0
"
/>
<div
class="metric-box"
v-if="
content.scenarioErrorReport > 0 ||
content.scenarioStepErrorReport > 0
"
>
v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0" />
<div class="metric-box" v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0">
<div class="value">
{{
content.scenarioStepErrorReport
? content.scenarioStepErrorReport
: 0
}}
{{ content.scenarioStepErrorReport ? content.scenarioStepErrorReport : 0 }}
</div>
<div class="name">FakeError</div>
</div>
<span v-show="showUnExecuteReport" class="ms-point-unexecute" />
<div v-show="showUnExecuteReport" class="metric-box">
<div class="value">
{{
content.scenarioStepPending ? content.scenarioStepPending : 0
}}
{{ content.scenarioStepPending ? content.scenarioStepPending : 0 }}
</div>
<div class="name">Pending</div>
</div>
@ -303,8 +230,7 @@ export default {
if (this.minutes > 60) {
this.hour = Math.round(this.minutes / 60);
this.minutes = Math.round(this.minutes % 60);
this.time =
this.hour + 'hour' + this.minutes + 'min' + this.seconds + 's';
this.time = this.hour + 'hour' + this.minutes + 'min' + this.seconds + 's';
}
} else {
this.time = this.totalTime + 'ms';
@ -396,10 +322,8 @@ export default {
},
showUnExecuteReport() {
return (
(this.content.scenarioStepPending &&
this.content.scenarioStepPending > 0) ||
(this.content.scenarioUnExecute &&
this.content.scenarioUnExecute > 0) ||
(this.content.scenarioStepPending && this.content.scenarioStepPending > 0) ||
(this.content.scenarioUnExecute && this.content.scenarioUnExecute > 0) ||
(this.content.unExecute && this.content.unExecute > 0)
);
},

View File

@ -2,64 +2,22 @@
<div class="metric-container">
<el-row type="flex">
<el-col>
<div style="font-size: 14px; color: #aaaaaa; float: left">
{{ $t('api_report.response_code') }} :
</div>
<div
style="
font-size: 14px;
color: #61c550;
margin-top: 2px;
margin-left: 10px;
float: left;
"
>
{{
request.responseResult.responseCode
? request.responseResult.responseCode
: '0'
}}
<div style="font-size: 14px; color: #aaaaaa; float: left">{{ $t('api_report.response_code') }} :</div>
<div style="font-size: 14px; color: #61c550; margin-top: 2px; margin-left: 10px; float: left">
{{ request.responseResult.responseCode ? request.responseResult.responseCode : '0' }}
</div>
</el-col>
<el-col>
<div style="font-size: 14px; color: #aaaaaa; float: left">
{{ $t('api_report.response_time') }} :
</div>
<div
style="
font-size: 14px;
color: #61c550;
margin-top: 2px;
margin-left: 10px;
float: left;
"
>
{{
request.responseResult.responseTime
? request.responseResult.responseTime
: 0
}}
<div style="font-size: 14px; color: #aaaaaa; float: left">{{ $t('api_report.response_time') }} :</div>
<div style="font-size: 14px; color: #61c550; margin-top: 2px; margin-left: 10px; float: left">
{{ request.responseResult.responseTime ? request.responseResult.responseTime : 0 }}
ms
</div>
</el-col>
<el-col>
<div style="font-size: 14px; color: #aaaaaa; float: left">
{{ $t('api_report.response_size') }} :
</div>
<div
style="
font-size: 14px;
color: #61c550;
margin-top: 2px;
margin-left: 10px;
float: left;
"
>
{{
request.responseResult.responseSize
? request.responseResult.responseSize
: 0
}}
<div style="font-size: 14px; color: #aaaaaa; float: left">{{ $t('api_report.response_size') }} :</div>
<div style="font-size: 14px; color: #61c550; margin-top: 2px; margin-left: 10px; float: left">
{{ request.responseResult.responseSize ? request.responseResult.responseSize : 0 }}
bytes
</div>
</el-col>

View File

@ -3,27 +3,14 @@
<div class="request-result">
<div @click="active">
<el-row :gutter="18" type="flex" align="middle" class="info">
<el-col
class="ms-req-name-col"
:span="18"
v-if="indexNumber != undefined"
>
<el-col class="ms-req-name-col" :span="18" v-if="indexNumber != undefined">
<el-tooltip :content="getName(request.name)" placement="top">
<span class="method ms-req-name">
<div class="el-step__icon is-text ms-api-col-create">
<div class="el-step__icon-inner">{{ indexNumber }}</div>
</div>
<i
class="icon el-icon-arrow-right"
:class="{ 'is-active': showActive }"
@click="active"
@click.stop
/>
<span
class="report-label-req"
@click="isLink"
v-if="redirect && resourceId"
>
<i class="icon el-icon-arrow-right" :class="{ 'is-active': showActive }" @click="active" @click.stop />
<span class="report-label-req" @click="isLink" v-if="redirect && resourceId">
{{ request.name }}
</span>
<span v-else>{{ getName(request.name) }}</span>
@ -36,21 +23,13 @@
effect="dark"
v-if="baseErrorCode && baseErrorCode !== ''"
:content="baseErrorCode"
style="
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
"
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
placement="bottom"
:open-delay="800"
>
:open-delay="800">
<div
:style="{
color: statusColor(
totalStatus ? totalStatus : request.status
),
}"
>
color: statusColor(totalStatus ? totalStatus : request.status),
}">
{{ baseErrorCode }}
</div>
</el-tooltip>
@ -60,21 +39,13 @@
<el-tooltip
effect="dark"
:content="request.responseResult.responseCode"
style="
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
"
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
placement="bottom"
:open-delay="800"
>
:open-delay="800">
<div
:style="{
color: statusColor(
totalStatus ? totalStatus : request.status
),
}"
>
color: statusColor(totalStatus ? totalStatus : request.status),
}">
{{ request.responseResult.responseCode }}
</div>
</el-tooltip>
@ -84,8 +55,7 @@
<div
:style="{
color: statusColor(totalStatus ? totalStatus : request.status),
}"
>
}">
{{ request.responseResult.responseTime }} ms
</div>
</el-col>
@ -94,10 +64,7 @@
<i class="el-icon-loading" style="font-size: 16px" />
{{ $t('commons.testing') }}
</el-tag>
<ms-api-report-status
:status="totalStatus || request.status"
v-else
/>
<ms-api-report-status :status="totalStatus || request.status" v-else />
</el-col>
</el-row>
</div>
@ -110,8 +77,7 @@
:request-type="requestType"
:request="requestInfo"
:console="console"
v-if="showActive"
/>
v-if="showActive" />
</div>
</el-collapse-transition>
</div>
@ -129,9 +95,7 @@ import { getShareContent } from '../../../../api/share';
import { getScenarioReportStepDetail } from '../../../../api/scenario-report';
import MsApiReportStatus from '../ApiReportStatus';
const {
getReportStatusColor,
} = require('../../../../business/commons/js/commons');
const { getReportStatusColor } = require('../../../../business/commons/js/commons');
export default {
name: 'MsRequestResult',
components: {
@ -204,10 +168,7 @@ export default {
handler(n) {
if (this.request.errorCode) {
this.baseErrorCode = this.request.errorCode;
} else if (
this.request.attachInfoMap &&
this.request.attachInfoMap.FAKE_ERROR
) {
} else if (this.request.attachInfoMap && this.request.attachInfoMap.FAKE_ERROR) {
if (this.request.attachInfoMap.FAKE_ERROR !== '') {
this.baseErrorCode = this.request.attachInfoMap.FAKE_ERROR;
}

View File

@ -8,23 +8,14 @@
</div>
</el-col>
<el-col :span="8">
<el-tooltip
effect="dark"
:content="request.url"
placement="bottom"
:open-delay="800"
>
<el-tooltip effect="dark" :content="request.url" placement="bottom" :open-delay="800">
<div class="url">{{ request.url }}</div>
</el-tooltip>
</el-col>
<el-col :span="8">
<div class="url">
{{ $t('api_report.start_time') }}{{
request.startTime | datetimeFormat(true)
}}
{{ $t('report.test_end_time') }}{{
request.endTime | datetimeFormat(true)
}}
{{ $t('api_report.start_time') }}{{ request.startTime | datetimeFormat(true) }}
{{ $t('report.test_end_time') }}{{ request.endTime | datetimeFormat(true) }}
</div>
</el-col>
</el-row>
@ -38,16 +29,14 @@
v-for="(sub, index) in request.subRequestResults"
:key="index"
:indexNumber="index"
:request="sub"
/>
:request="sub" />
</el-tab-pane>
<el-tab-pane :label="$t('api_report.request_result')" name="result">
<ms-response-text
:console="console"
:request-type="requestType"
:response="request.responseResult"
:request="request"
/>
:request="request" />
</el-tab-pane>
</el-tabs>
<div v-else>
@ -56,8 +45,7 @@
:request-type="requestType"
v-if="isCodeEditAlive"
:response="request.responseResult"
:request="request"
/>
:request="request" />
</div>
</div>
</el-collapse-transition>

View File

@ -5,28 +5,14 @@
<el-row :gutter="10" type="flex" align="middle" class="info">
<el-col :span="6" v-if="indexNumber != undefined">
<div class="method">
<div
style="
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
"
>
<div
class="el-step__icon is-text ms-api-col"
v-if="indexNumber % 2 == 0"
>
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
<div class="el-step__icon is-text ms-api-col" v-if="indexNumber % 2 == 0">
<div class="el-step__icon-inner">{{ indexNumber + 1 }}</div>
</div>
<div class="el-step__icon is-text ms-api-col-create" v-else>
<div class="el-step__icon-inner">{{ indexNumber + 1 }}</div>
</div>
<i
class="icon el-icon-arrow-right"
:class="{ 'is-active': isActive }"
@click="active"
@click.stop
/>
<i class="icon el-icon-arrow-right" :class="{ 'is-active': isActive }" @click="active" @click.stop />
{{ getName(request.name) }}
</div>
</div>
@ -40,14 +26,9 @@
<div class="url">
<el-tooltip
:content="request.url"
style="
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
"
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
placement="bottom"
:open-delay="800"
>
:open-delay="800">
<div>
{{ request.url }}
</div>
@ -55,26 +36,17 @@
</div>
</el-col>
<el-col :span="5">
<el-tooltip
effect="dark"
:content="request.responseResult.responseCode"
placement="bottom"
:open-delay="800"
>
<el-tooltip effect="dark" :content="request.responseResult.responseCode" placement="bottom" :open-delay="800">
<div class="url" style="color: #5daf34">
{{ request.responseResult.responseCode }}
</div>
</el-tooltip>
</el-col>
<el-col :span="3">
{{ request.responseResult.responseTime }} ms
</el-col>
<el-col :span="3"> {{ request.responseResult.responseTime }} ms </el-col>
<el-col :span="2">
<div class="success">
<el-tag size="mini" type="success" v-if="request.success">
Success
</el-tag>
<el-tag size="mini" type="success" v-if="request.success"> Success </el-tag>
<el-tag size="mini" type="danger" v-else> Error </el-tag>
</div>
</el-col>
@ -86,8 +58,7 @@
:scenario-name="scenarioName"
:request-type="requestType"
v-if="isActive"
:request="request"
/>
:request="request" />
</div>
</el-collapse-transition>
</div>

View File

@ -8,21 +8,12 @@
</div>
</el-col>
<el-col :span="8">
<el-tooltip
effect="dark"
:content="request.url"
placement="bottom"
:open-delay="800"
>
<el-tooltip effect="dark" :content="request.url" placement="bottom" :open-delay="800">
<div class="url">{{ request.url }}</div>
</el-tooltip>
</el-col>
<el-col :span="8">
<div class="url">
{{ $t('api_report.start_time') }}{{
request.startTime | datetimeFormat(true)
}}
</div>
<div class="url">{{ $t('api_report.start_time') }}{{ request.startTime | datetimeFormat(true) }}</div>
</el-col>
</el-row>
</div>
@ -32,8 +23,7 @@
:request-type="requestType"
v-if="isCodeEditAlive"
:response="request.responseResult"
:request="request"
/>
:request="request" />
</div>
</el-collapse-transition>
</div>

View File

@ -6,8 +6,7 @@
:class="'body-pane'"
:label="$t('api_test.definition.request.response_body')"
name="body"
class="pane"
>
class="pane">
<ms-sql-result-table v-if="isSqlType" :body="response.body" />
<ms-code-edit
v-if="!isSqlType"
@ -15,39 +14,22 @@
:read-only="true"
:data="response.body"
:modes="modes"
ref="codeEdit"
/>
ref="codeEdit" />
</el-tab-pane>
<el-tab-pane
:label="$t('api_test.definition.request.response_header')"
name="headers"
class="pane"
>
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane">
<pre>{{ response.headers }}</pre>
</el-tab-pane>
<el-tab-pane
:label="$t('api_report.assertions')"
name="assertions"
class="pane assertions"
>
<el-tab-pane :label="$t('api_report.assertions')" name="assertions" class="pane assertions">
<ms-assertion-results :assertions="response.assertions" />
</el-tab-pane>
<el-tab-pane
:label="$t('api_test.request.extract.label')"
name="label"
class="pane"
>
<el-tab-pane :label="$t('api_test.request.extract.label')" name="label" class="pane">
<pre>{{ response.vars }}</pre>
</el-tab-pane>
<el-tab-pane
:label="$t('api_report.request_body')"
name="request_body"
class="pane"
>
<el-tab-pane :label="$t('api_report.request_body')" name="request_body" class="pane">
<div class="ms-div">
{{ $t('api_test.request.address') }} :
<pre>{{ request.url }}</pre>
@ -66,26 +48,14 @@
</div>
</el-tab-pane>
<el-tab-pane
v-if="activeName == 'body'"
:disabled="true"
name="mode"
class="pane assertions"
>
<el-tab-pane v-if="activeName == 'body'" :disabled="true" name="mode" class="pane assertions">
<template v-slot:label>
<ms-dropdown
v-if="request.method === 'SQL'"
:commands="sqlModes"
:default-command="mode"
@command="sqlModeChange"
/>
<ms-dropdown
v-else
:commands="modes"
:default-command="mode"
@command="modeChange"
ref="modeDropdown"
/>
@command="sqlModeChange" />
<ms-dropdown v-else :commands="modes" :default-command="mode" @command="modeChange" ref="modeDropdown" />
</template>
</el-tab-pane>
</el-tabs>
@ -97,12 +67,7 @@
import MsAssertionResults from './AssertionResults';
import MsCodeEdit from 'metersphere-frontend/src/components/MsCodeEdit';
import MsDropdown from '../../../../business/commons/MsDropdown';
import {
BODY_FORMAT,
RequestFactory,
Request,
SqlRequest,
} from '../../../../business/definition/model/ApiTestModel';
import { BODY_FORMAT, RequestFactory, Request, SqlRequest } from '../../../../business/definition/model/ApiTestModel';
import MsSqlResultTable from './SqlResultTable';
export default {
@ -156,8 +121,7 @@ export default {
computed: {
isSqlType() {
return (
(this.requestType === RequestFactory.TYPES.SQL ||
this.request.method === RequestFactory.TYPES.SQL) &&
(this.requestType === RequestFactory.TYPES.SQL || this.request.method === RequestFactory.TYPES.SQL) &&
this.response.responseCode === '200' &&
this.mode === 'table'
);

View File

@ -4,10 +4,8 @@
v-if="
(node.children && node.children.length > 0) ||
node.unsolicited ||
(node.type &&
this.stepFilter.get('AllSamplerProxy').indexOf(node.type) === -1)
"
>
(node.type && this.stepFilter.get('AllSamplerProxy').indexOf(node.type) === -1)
">
<el-card class="ms-card">
<div class="el-step__icon is-text ms-api-col">
<div class="el-step__icon-inner">
@ -15,11 +13,7 @@
</div>
</div>
<el-tooltip effect="dark" :content="node.label" placement="top">
<el-link
v-if="node.redirect"
class="report-label-head"
@click="isLink"
>
<el-link v-if="node.redirect" class="report-label-head" @click="isLink">
{{ getLabel(node.label) }}
</el-link>
<span v-else>{{ getLabel(node.label) }}</span>
@ -40,8 +34,7 @@
:isActive="isActive"
:is-share="isShare"
:share-id="shareId"
v-on:requestResult="requestResult"
/>
v-on:requestResult="requestResult" />
</div>
</div>
</template>
@ -113,9 +106,7 @@ export default {
computed: {
assertion() {
return (
this.scenario.passAssertions + ' / ' + this.scenario.totalAssertions
);
return this.scenario.passAssertions + ' / ' + this.scenario.totalAssertions;
},
success() {
return this.scenario.error === 0;
@ -173,8 +164,7 @@ export default {
.report-label-head {
border-bottom: 1px solid #303133;
color: #303133;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
font-size: 13px;
}

View File

@ -1,27 +1,11 @@
<template>
<el-card class="scenario-results">
<div v-if="errorReport > 0">
<el-tooltip
:content="$t('api_test.automation.open_expansion')"
placement="top"
effect="light"
>
<i
class="el-icon-circle-plus-outline ms-open-btn ms-open-btn-left"
v-prevent-re-click
@click="openExpansion"
/>
<el-tooltip :content="$t('api_test.automation.open_expansion')" placement="top" effect="light">
<i class="el-icon-circle-plus-outline ms-open-btn ms-open-btn-left" v-prevent-re-click @click="openExpansion" />
</el-tooltip>
<el-tooltip
:content="$t('api_test.automation.close_expansion')"
placement="top"
effect="light"
>
<i
class="el-icon-remove-outline ms-open-btn"
size="mini"
@click="closeExpansion"
/>
<el-tooltip :content="$t('api_test.automation.close_expansion')" placement="top" effect="light">
<i class="el-icon-remove-outline ms-open-btn" size="mini" @click="closeExpansion" />
</el-tooltip>
</div>
<el-tree
@ -31,21 +15,15 @@
:filter-node-method="filterNode"
highlight-current
class="ms-tree ms-report-tree"
ref="resultsTree"
>
<span
slot-scope="{ node, data }"
style="width: 99%"
@click="nodeClick(node)"
>
ref="resultsTree">
<span slot-scope="{ node, data }" style="width: 99%" @click="nodeClick(node)">
<ms-scenario-result
:node="data"
:console="console"
v-on:requestResult="requestResult"
:isActive="isActive"
:is-share="isShare"
:share-id="shareId"
/>
:share-id="shareId" />
</span>
</el-tree>
</el-card>
@ -82,11 +60,7 @@ export default {
},
computed: {
isUi() {
return (
this.report &&
this.report.reportType &&
this.report.reportType.startsWith('UI')
);
return this.report && this.report.reportType && this.report.reportType.startsWith('UI');
},
},
methods: {
@ -97,11 +71,7 @@ export default {
if (!value) return true;
if (data.value) {
if (value === 'FAKE_ERROR') {
if (
data.errorCode &&
data.errorCode !== '' &&
data.value.status === 'FAKE_ERROR'
) {
if (data.errorCode && data.errorCode !== '' && data.value.status === 'FAKE_ERROR') {
return true;
}
} else if (value === 'PENDING') {
@ -180,8 +150,7 @@ export default {
:deep(.el-checkbox) {
color: #303133;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
font-size: 13px;
font-weight: normal;
}

View File

@ -6,22 +6,14 @@
:data="table.tableData"
border
size="mini"
highlight-current-row
>
<el-table-column
v-for="(title, index) in table.titles"
:key="index"
:label="title"
min-width="150px"
>
highlight-current-row>
<el-table-column v-for="(title, index) in table.titles" :key="index" :label="title" min-width="150px">
<template v-slot:default="scope">
<el-popover placement="top" trigger="click">
<el-container>
<div>{{ scope.row[title] }}</div>
</el-container>
<span class="table-content" slot="reference">{{
scope.row[title]
}}</span>
<span class="table-content" slot="reference">{{ scope.row[title] }}</span>
</el-popover>
</template>
</el-table-column>
@ -50,10 +42,7 @@ export default {
if (this.tables.length > 1) {
for (let i = 0; i < this.tables.length; i++) {
if (this.tables[i].titles.length === 1 && i < this.tables.length - 1) {
this.tables[i].tableData.splice(
this.tables[i].tableData.length - 1,
1
);
this.tables[i].tableData.splice(this.tables[i].tableData.length - 1, 1);
}
}

View File

@ -4,28 +4,19 @@
:title="$t('api_test.automation.add_scenario')"
:visible.sync="visible"
width="45%"
:destroy-on-close="true"
>
:destroy-on-close="true">
<el-form
:model="scenarioForm"
label-position="right"
label-width="100px"
size="small"
:rules="rule"
ref="scenarioForm"
>
ref="scenarioForm">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input
v-model="scenarioForm.name"
autocomplete="off"
:placeholder="$t('commons.name')"
/>
<el-input v-model="scenarioForm.name" autocomplete="off" :placeholder="$t('commons.name')" />
</el-form-item>
<el-form-item
:label="$t('test_track.module.module')"
prop="apiScenarioModuleId"
>
<el-form-item :label="$t('test_track.module.module')" prop="apiScenarioModuleId">
<ms-select-tree
size="small"
:data="moduleOptions"
@ -33,66 +24,50 @@
@getValue="setModule"
:obj="moduleObj"
clearable
checkStrictly
/>
checkStrictly />
</el-form-item>
<el-form-item
:label="$t('api_test.automation.scenario.principal')"
prop="principal"
>
<el-form-item :label="$t('api_test.automation.scenario.principal')" prop="principal">
<el-select
v-model="scenarioForm.principal"
:placeholder="$t('api_test.automation.scenario.principal')"
filterable
size="small"
style="width: 100%"
>
style="width: 100%">
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.id + ' (' + item.name + ')'"
:value="item.id"
>
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item
:label="$t('api_test.automation.scenario.follow_people')"
prop="followPeople"
>
<el-form-item :label="$t('api_test.automation.scenario.follow_people')" prop="followPeople">
<el-select
v-model="scenarioForm.follows"
multiple
:placeholder="$t('api_test.automation.scenario.follow_people')"
filterable
size="small"
style="width: 100%"
>
style="width: 100%">
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.id + ' (' + item.name + ')'"
:value="item.id"
>
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item
:label="$t('commons.description')"
prop="description"
style="margin-bottom: 29px"
>
<el-form-item :label="$t('commons.description')" prop="description" style="margin-bottom: 29px">
<el-input
class="ms-http-textarea"
v-model="scenarioForm.description"
type="textarea"
:autosize="{ minRows: 2, maxRows: 10 }"
:rows="2"
size="small"
/>
size="small" />
</el-form-item>
</el-form>
@ -102,8 +77,7 @@
:isShow="true"
:title="$t('commons.edit_info')"
@saveAsEdit="saveScenario(true)"
@confirm="saveScenario"
>
@confirm="saveScenario">
</ms-dialog-footer>
</template>
</el-dialog>
@ -111,10 +85,7 @@
<script>
import { getMaintainer } from '@/api/project';
import {
getCurrentProjectID,
getCurrentUser,
} from 'metersphere-frontend/src/utils/token';
import { getCurrentProjectID, getCurrentUser } from 'metersphere-frontend/src/utils/token';
import { getUUID } from 'metersphere-frontend/src/utils';
import MsDialogFooter from 'metersphere-frontend/src/components/MsDialogFooter';
import { saveScenario } from '@/business/automation/api-automation';
@ -184,9 +155,7 @@ export default {
this.scenarioForm.status = 'Underway';
this.scenarioForm.level = 'P0';
if (saveAs) {
this.scenarioForm.request = JSON.stringify(
this.scenarioForm.request
);
this.scenarioForm.request = JSON.stringify(this.scenarioForm.request);
this.$emit('saveAsEdit', this.scenarioForm);
this.visible = false;
} else {
@ -221,10 +190,7 @@ export default {
open(currentModule) {
this.scenarioForm = { principal: getCurrentUser().id };
this.currentModule = currentModule;
if (
this.scenarioForm.apiScenarioModuleId === undefined &&
!currentModule.id
) {
if (this.scenarioForm.apiScenarioModuleId === undefined && !currentModule.id) {
this.scenarioForm.apiScenarioModuleId = this.moduleOptions[0].id;
} else if (currentModule.id) {
this.scenarioForm.apiScenarioModuleId = currentModule.id;

View File

@ -3,17 +3,9 @@
<el-card>
<el-form :model="request" label-width="auto" ref="request">
<el-form-item :label="$t('api_test.request.name')" prop="name">
<el-input
v-model="request.name"
maxlength="200"
show-word-limit
size="small"
/>
<el-input v-model="request.name" maxlength="200" show-word-limit size="small" />
</el-form-item>
<el-form-item
:label="$t('api_test.definition.api_type')"
prop="protocol"
>
<el-form-item :label="$t('api_test.definition.api_type')" prop="protocol">
<el-radio v-model="request.protocol" label="HTTP">HTTP</el-radio>
<el-radio v-model="request.protocol" label="DUBBO">DUBBO</el-radio>
<el-radio v-model="request.protocol" label="SQL">SQL</el-radio>
@ -26,26 +18,22 @@
:current-api="request"
@saveAs="editApi"
:currentProtocol="request.protocol"
v-if="request.protocol === 'HTTP'"
/>
v-if="request.protocol === 'HTTP'" />
<ms-debug-jdbc-page
:scenario="true"
:currentProtocol="request.protocol"
@saveAs="editApi"
v-if="request.protocol === 'SQL'"
/>
v-if="request.protocol === 'SQL'" />
<ms-debug-tcp-page
:scenario="true"
:currentProtocol="request.protocol"
@saveAs="editApi"
v-if="request.protocol === 'TCP'"
/>
v-if="request.protocol === 'TCP'" />
<ms-debug-dubbo-page
:scenario="true"
:currentProtocol="request.protocol"
@saveAs="editApi"
v-if="request.protocol === 'DUBBO'"
/>
v-if="request.protocol === 'DUBBO'" />
</el-card>
</div>
</template>

View File

@ -4,8 +4,7 @@
:visible.sync="dialogVisible"
width="30%"
:destroy-on-close="true"
:before-close="handleClose"
>
:before-close="handleClose">
<div v-loading="result">
<div v-for="pe in data" :key="pe.id" style="margin-left: 20px">
{{ getProjectName(pe.id) }}
@ -13,30 +12,18 @@
v-model="pe['selectEnv']"
placeholder="请选择环境"
style="margin-left: 10px; margin-top: 10px"
size="small"
>
size="small">
<el-option
v-for="(environment, index) in pe.envs"
:key="index"
:label="environment.name"
:value="environment.id"
/>
<el-button
class="ms-scenario-button"
size="mini"
type="primary"
@click="openEnvironmentConfig(pe.id)"
>
:value="environment.id" />
<el-button class="ms-scenario-button" size="mini" type="primary" @click="openEnvironmentConfig(pe.id)">
{{ $t('api_test.environment.environment_config') }}
</el-button>
<template v-slot:empty>
<div class="empty-environment">
<el-button
class="ms-scenario-button"
size="mini"
type="primary"
@click="openEnvironmentConfig(pe.id)"
>
<el-button class="ms-scenario-button" size="mini" type="primary" @click="openEnvironmentConfig(pe.id)">
{{ $t('api_test.environment.environment_config') }}
</el-button>
</div>
@ -47,16 +34,11 @@
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small"> </el-button>
<el-button type="primary" @click="handleConfirm" size="small"
> </el-button
>
<el-button type="primary" @click="handleConfirm" size="small"> </el-button>
</span>
<!-- 环境配置 -->
<api-environment-config
ref="environmentConfig"
@close="environmentConfigClose"
/>
<api-environment-config ref="environmentConfig" @close="environmentConfigClose" />
</el-dialog>
</template>

View File

@ -1,11 +1,7 @@
<template>
<div class="scenario-div" v-loading="result">
<slot name="version"></slot>
<ms-search
:condition.sync="condition"
:base-search-tip="$t('commons.search_by_id_name_tag')"
@search="search"
>
<ms-search :condition.sync="condition" :base-search-tip="$t('commons.search_by_id_name_tag')" @search="search">
</ms-search>
<ms-table
@ -27,16 +23,14 @@
@refresh="search(projectId)"
@callBackSelectAll="callBackSelectAll"
@callBackSelect="callBackSelect"
ref="scenarioTable"
>
ref="scenarioTable">
<ms-table-column
prop="deleteTime"
sortable
v-if="this.trashEnable"
:fields-width="fieldsWidth"
:label="$t('commons.delete_time')"
min-width="150px"
>
min-width="150px">
<template v-slot:default="scope">
<span>{{ scope.row.deleteTime | datetimeFormat }}</span>
</template>
@ -47,8 +41,7 @@
:fields-width="fieldsWidth"
v-if="this.trashEnable"
:label="$t('commons.delete_user')"
min-width="120"
/>
min-width="120" />
<span v-for="item in fields" :key="item.key">
<ms-table-column
@ -57,8 +50,7 @@
label="ID"
sortable
min-width="120px"
v-if="item.id == 'num' && !customNum"
>
v-if="item.id == 'num' && !customNum">
<template slot-scope="scope" v-if="!trashEnable">
<el-tooltip :content="$t('commons.edit')">
<a style="cursor: pointer" @click="edit(scope.row)">
@ -74,8 +66,7 @@
:fields-width="fieldsWidth"
min-width="120px"
prop="customNum"
v-if="item.id == 'num' && customNum"
>
v-if="item.id == 'num' && customNum">
<template slot-scope="scope">
<el-tooltip :content="$t('commons.edit')">
<a style="cursor: pointer" @click="edit(scope.row)">
@ -91,8 +82,7 @@
:label="$t('api_test.automation.scenario_name')"
min-width="150px"
prop="name"
sortable
/>
sortable />
<ms-table-column
:field="item"
@ -101,8 +91,7 @@
:label="$t('api_test.automation.case_level')"
min-width="130px"
prop="level"
sortable
>
sortable>
<template v-slot:default="scope">
<priority-table-item :value="scope.row.level" />
</template>
@ -115,8 +104,7 @@
:fields-width="fieldsWidth"
:filters="!trashEnable ? scenarioFilters.STATUS_FILTERS : null"
prop="status"
min-width="120px"
>
min-width="120px">
<template v-slot:default="scope">
<plan-status-table-item :value="scope.row.status" />
</template>
@ -128,8 +116,7 @@
:showOverflowTooltip="false"
:label="$t('api_test.automation.tag')"
min-width="120px"
prop="tags"
>
prop="tags">
<template v-slot:default="scope">
<ms-tag
v-for="(itemName, index) in scope.row.tags"
@ -137,12 +124,9 @@
type="success"
effect="plain"
:content="itemName"
:show-tooltip="
scope.row.tags.length === 1 && itemName.length * 12 <= 120
"
:show-tooltip="scope.row.tags.length === 1 && itemName.length * 12 <= 120"
:showTooltip="true"
style="margin-left: 0px; margin-right: 2px"
/>
style="margin-left: 0px; margin-right: 2px" />
<span />
</template>
</ms-table-column>
@ -153,8 +137,7 @@
:fields-width="fieldsWidth"
:filters="versionFilters"
min-width="100px"
prop="versionId"
>
prop="versionId">
<template v-slot:default="scope">
<span>{{ scope.row.versionName }}</span>
</template>
@ -166,8 +149,7 @@
:fields-width="fieldsWidth"
prop="principalName"
min-width="120px"
sortable
/>
sortable />
<ms-table-column
:label="$t('api_test.automation.creator')"
:filters="userFilters"
@ -175,16 +157,14 @@
:fields-width="fieldsWidth"
prop="creatorName"
min-width="120px"
sortable="custom"
/>
sortable="custom" />
<ms-table-column
:field="item"
:fields-width="fieldsWidth"
:filters="environmentsFilters"
prop="environmentMap"
:label="$t('commons.environment')"
min-width="180"
>
min-width="180">
<template v-slot:default="{ row }">
<div v-if="row.environmentMap">
<span v-for="(k, v, index) in row.environmentMap" :key="index">
@ -199,20 +179,11 @@
<el-popover placement="top" width="350" trigger="click">
<div v-for="(k, v, index) in row.environmentMap" :key="index">
<span class="plan-case-env"
>{{ v }}:
<el-tag type="success" size="mini" effect="plain">{{
k
}}</el-tag
>{{ v }}: <el-tag type="success" size="mini" effect="plain">{{ k }}</el-tag
><br />
</span>
</div>
<el-link
v-if="index === 1"
slot="reference"
type="info"
:underline="false"
icon="el-icon-more"
/>
<el-link v-if="index === 1" slot="reference" type="info" :underline="false" icon="el-icon-more" />
</el-popover>
</span>
</div>
@ -225,8 +196,7 @@
:label="$t('commons.update_time')"
sortable
prop="updateTime"
min-width="180px"
>
min-width="180px">
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | datetimeFormat }}</span>
</template>
@ -237,8 +207,7 @@
:label="$t('commons.create_time')"
sortable
prop="createTime"
min-width="180px"
>
min-width="180px">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | datetimeFormat }}</span>
</template>
@ -249,8 +218,7 @@
:fields-width="fieldsWidth"
:label="$t('api_test.automation.step')"
prop="stepTotal"
min-width="80px"
/>
min-width="80px" />
<ms-table-column
:label="$t('api_test.automation.last_result')"
:filters="resultFilters"
@ -258,13 +226,9 @@
:fields-width="fieldsWidth"
sortable
prop="lastResult"
min-width="130px"
>
min-width="130px">
<template v-slot:default="{ row }">
<el-link
@click="showReport(row)"
:disabled="!row.lastResult || row.lastResult === 'PENDING'"
>
<el-link @click="showReport(row)" :disabled="!row.lastResult || row.lastResult === 'PENDING'">
<ms-api-report-status :status="row.lastResult" />
</el-link>
</template>
@ -275,8 +239,7 @@
:fields-width="fieldsWidth"
:label="$t('api_test.automation.passing_rate')"
prop="passRate"
min-width="120px"
/>
min-width="120px" />
</span>
<template v-slot:opt-before="scope">
@ -287,28 +250,15 @@
icon="el-icon-video-play"
class="run-button"
style="margin-right: 10px"
v-permission="['PROJECT_API_SCENARIO:READ+RUN']"
/>
<el-tooltip
:content="$t('report.stop_btn')"
placement="top"
:enterable="false"
v-else
>
v-permission="['PROJECT_API_SCENARIO:READ+RUN']" />
<el-tooltip :content="$t('report.stop_btn')" placement="top" :enterable="false" v-else>
<el-button
v-if="!trashEnable"
@click.once="stop(scope.row)"
size="mini"
style="
color: white;
padding: 0;
width: 28px;
height: 28px;
margin-right: 10px;
"
style="color: white; padding: 0; width: 28px; height: 28px; margin-right: 10px"
class="stop-btn"
circle
>
circle>
<div style="transform: scale(0.72)">
<span style="margin-left: -3.5px; font-weight: bold">STOP</span>
</div>
@ -324,17 +274,11 @@
@openScenario="openScenario"
@showCaseRef="showScenarioRef"
v-if="!trashEnable"
style="display: contents"
/>
style="display: contents" />
</template>
</ms-table>
<ms-table-pagination
:change="search"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:total="total"
/>
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total" />
<div>
<!-- 执行结果 -->
@ -344,8 +288,7 @@
direction="rtl"
:withHeader="true"
:modal="false"
size="90%"
>
size="90%">
<sysn-api-report-detail
@refresh="search"
:debug="true"
@ -353,8 +296,7 @@
:scenarioId="scenarioId"
:infoDb="infoDb"
:report-id="reportId"
:currentProjectId="projectId"
/>
:currentProjectId="projectId" />
</el-drawer>
<!-- 执行结果 -->
<el-drawer
@ -363,16 +305,14 @@
direction="rtl"
:withHeader="true"
:modal="false"
size="90%"
>
size="90%">
<ms-api-report-detail
@invisible="showReportVisible = false"
@refresh="search"
:infoDb="infoDb"
:show-cancel-button="false"
:report-id="showReportId"
:currentProjectId="projectId"
/>
:currentProjectId="projectId" />
</el-drawer>
<!--测试计划-->
<el-drawer
@ -382,15 +322,13 @@
:withHeader="false"
:title="$t('test_track.plan_view.test_result')"
:modal="false"
size="90%"
>
size="90%">
<ms-test-plan-list
@addTestPlan="addTestPlan(arguments)"
@cancel="cancel"
ref="testPlanList"
:scenario-condition="condition"
:row="selectRows"
/>
:row="selectRows" />
</el-drawer>
</div>
@ -399,16 +337,14 @@
@batchEdit="batchEdit"
:typeArr="typeArr"
:value-arr="valueArr"
:dialog-title="$t('test_track.case.batch_edit_case')"
/>
:dialog-title="$t('test_track.case.batch_edit_case')" />
<batch-move @refresh="search" @moveSave="moveSave" ref="testBatchMove" />
<ms-api-run-mode
:request="runRequest"
:project-id="projectId"
@close="search"
@handleRunBatch="handleRunBatch"
ref="apiBatchRun"
/>
ref="apiBatchRun" />
<ms-run
:debug="true"
:environment="projectEnvMap"
@ -420,33 +356,20 @@
:run-data="debugData"
@runRefresh="runRefresh"
@errorRefresh="errorRefresh"
ref="runTest"
/>
ref="runTest" />
<ms-task-center ref="taskCenter" :show-menu="false" />
<mx-relationship-graph-drawer
v-xpack
:graph-data="graphData"
ref="relationshipGraph"
/>
<mx-relationship-graph-drawer v-xpack :graph-data="graphData" ref="relationshipGraph" />
<!-- 删除接口提示 -->
<scenario-delete-confirm
ref="apiDeleteConfirmVersion"
@handleDelete="_handleDelete"
/>
<scenario-delete-confirm ref="apiDeleteConfirmVersion" @handleDelete="_handleDelete" />
<!-- 删除场景弹窗 -->
<api-delete-confirm
:has-ref="hasRef"
:show-scenario="showScenario"
@showCaseRef="showScenarioRef"
@handleDeleteCase="handleDeleteScenario"
ref="apiDeleteConfirm"
/>
ref="apiDeleteConfirm" />
<!-- 引用场景弹窗 -->
<ms-show-reference
ref="viewRef"
@showCaseRef="showScenarioRef"
@openScenario="openScenario"
/>
<ms-show-reference ref="viewRef" @showCaseRef="showScenarioRef" @openScenario="openScenario" />
</div>
</template>
@ -478,20 +401,9 @@ import {
} from '@/api/scenario';
import { getMaintainer, getProject } from '@/api/project';
import { getProjectVersions, versionEnableByProjectId } from '@/api/xpack';
import {
getCurrentProjectID,
getCurrentUserId,
} from 'metersphere-frontend/src/utils/token';
import {
downloadFile,
getUUID,
objToStrMap,
strMapToObj,
} from 'metersphere-frontend/src/utils';
import {
hasLicense,
hasPermission,
} from 'metersphere-frontend/src/utils/permission';
import { getCurrentProjectID, getCurrentUserId } from 'metersphere-frontend/src/utils/token';
import { downloadFile, getUUID, objToStrMap, strMapToObj } from 'metersphere-frontend/src/utils';
import { hasLicense, hasPermission } from 'metersphere-frontend/src/utils/permission';
import { API_SCENARIO_CONFIGS } from 'metersphere-frontend/src/components/search/search-components';
import { API_SCENARIO_LIST } from 'metersphere-frontend/src/utils/constants';
import {
@ -506,10 +418,7 @@ import MsTable from 'metersphere-frontend/src/components/table/MsTable';
import MsTableColumn from 'metersphere-frontend/src/components/table/MsTableColumn';
import HeaderLabelOperate from 'metersphere-frontend/src/components/head/HeaderLabelOperate';
import { getGraphByCondition } from '@/api/graph';
import {
API_SCENARIO_CONFIGS_TRASH,
TYPE_TO_C,
} from '@/business/automation/scenario/Setting';
import { API_SCENARIO_CONFIGS_TRASH, TYPE_TO_C } from '@/business/automation/scenario/Setting';
import MsTableSearchBar from 'metersphere-frontend/src/components/MsTableSearchBar';
import MsTableAdvSearchBar from 'metersphere-frontend/src/components/search/MsTableAdvSearchBar';
import ListItemDeleteConfirm from 'metersphere-frontend/src/components/ListItemDeleteConfirm';
@ -542,39 +451,26 @@ export default {
MsShowReference,
ScenarioDeleteConfirm,
MsApiReportStatus: () => import('../report/ApiReportStatus'),
HeaderCustom: () =>
import('metersphere-frontend/src/components/head/HeaderCustom'),
HeaderCustom: () => import('metersphere-frontend/src/components/head/HeaderCustom'),
BatchMove: () => import('@/business/commons/BatchMove'),
EnvironmentSelect: () =>
import('@/business/environment/components/EnvironmentSelect'),
EnvironmentSelect: () => import('@/business/environment/components/EnvironmentSelect'),
BatchEdit: () => import('@/business/commons/BatchEdit'),
PlanStatusTableItem: () => import('@/business/commons/PlanStatusTableItem'),
PriorityTableItem: () => import('@/business/commons/PriorityTableItem'),
MsTableHeaderSelectPopover: () =>
import(
'metersphere-frontend/src/components/table/MsTableHeaderSelectPopover'
),
MsTablePagination: () =>
import('metersphere-frontend/src/components/pagination/TablePagination'),
MsTableHeaderSelectPopover: () => import('metersphere-frontend/src/components/table/MsTableHeaderSelectPopover'),
MsTablePagination: () => import('metersphere-frontend/src/components/pagination/TablePagination'),
MsTableMoreBtn: () => import('./TableMoreBtn'),
ShowMoreBtn: () => import('@/business/commons/ShowMoreBtn'),
MsTableHeader: () =>
import('metersphere-frontend/src/components/MsTableHeader'),
MsTableHeader: () => import('metersphere-frontend/src/components/MsTableHeader'),
MsTag: () => import('metersphere-frontend/src/components/MsTag'),
MsApiReportDetail: () => import('../report/ApiReportDetail'),
SysnApiReportDetail: () => import('../report/SyncApiReportDetail'),
MsScenarioExtendButtons: () =>
import('@/business/automation/scenario/ScenarioExtendBtns'),
MsScenarioExtendButtons: () => import('@/business/automation/scenario/ScenarioExtendBtns'),
MsTestPlanList: () => import('./testplan/TestPlanList'),
MsTableOperatorButton: () =>
import('metersphere-frontend/src/components/MsTableOperatorButton'),
MsTaskCenter: () =>
import('metersphere-frontend/src/components/task/TaskCenter'),
MsTableOperatorButton: () => import('metersphere-frontend/src/components/MsTableOperatorButton'),
MsTaskCenter: () => import('metersphere-frontend/src/components/task/TaskCenter'),
MsRun: () => import('./DebugRun'),
MxRelationshipGraphDrawer: () =>
import(
'metersphere-frontend/src/components/graph/MxRelationshipGraphDrawer'
),
MxRelationshipGraphDrawer: () => import('metersphere-frontend/src/components/graph/MxRelationshipGraphDrawer'),
},
props: {
referenced: {
@ -629,9 +525,7 @@ export default {
fieldsWidth: getCustomTableWidth('API_SCENARIO'),
screenHeight: 'calc(100vh - 180px)', //,
condition: {
components: this.trashEnable
? API_SCENARIO_CONFIGS_TRASH
: API_SCENARIO_CONFIGS,
components: this.trashEnable ? API_SCENARIO_CONFIGS_TRASH : API_SCENARIO_CONFIGS,
},
projectId: '',
scenarioId: '',
@ -906,16 +800,11 @@ export default {
},
methods: {
generateGraph() {
if (
getSelectDataCounts(this.condition, this.total, this.selectRows) > 100
) {
if (getSelectDataCounts(this.condition, this.total, this.selectRows) > 100) {
this.$warning(this.$t('test_track.case.generate_dependencies_warning'));
return;
}
getGraphByCondition(
'API_SCENARIO',
buildBatchParam(this, this.$refs.scenarioTable.selectIds)
).then((data) => {
getGraphByCondition('API_SCENARIO', buildBatchParam(this, this.$refs.scenarioTable.selectIds)).then((data) => {
this.graphData = data.data;
this.$refs.relationshipGraph.open();
});
@ -1015,11 +904,7 @@ export default {
}
}
if (this.condition.projectId) {
this.result = getScenarioList(
this.currentPage,
this.pageSize,
this.condition
).then((response) => {
this.result = getScenarioList(this.currentPage, this.pageSize, this.condition).then((response) => {
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
@ -1052,10 +937,7 @@ export default {
this.planVisible = true;
},
handleBatchEdit() {
this.$refs.batchEdit.setScenarioSelectRows(
this.$refs.scenarioTable.selectRows,
'scenario'
);
this.$refs.batchEdit.setScenarioSelectRows(this.$refs.scenarioTable.selectRows, 'scenario');
if (this.condition.selectAll) {
this.condition.ids = [];
let param = {};
@ -1077,11 +959,7 @@ export default {
},
handleBatchCopy() {
this.isMoveBatch = false;
this.$refs.testBatchMove.open(
this.moduleTree,
this.$refs.scenarioTable.selectIds,
this.moduleOptionsNew
);
this.$refs.testBatchMove.open(this.moduleTree, this.$refs.scenarioTable.selectIds, this.moduleOptionsNew);
},
moveSave(param) {
this.buildBatchParam(param);
@ -1298,13 +1176,10 @@ export default {
this.hasRef = false;
checkBeforeDelete(param).then((response) => {
let checkResult = response.data;
let alertMsg =
this.$t('load_test.delete_threadgroup_confirm') + ' ';
let alertMsg = this.$t('load_test.delete_threadgroup_confirm') + ' ';
if (checkResult.deleteFlag) {
alertMsg =
this.$t('api_definition.scenario_is_referenced', [
checkResult.refCount,
]) +
this.$t('api_definition.scenario_is_referenced', [checkResult.refCount]) +
', ' +
this.$t('api_test.is_continue') +
' ';
@ -1329,10 +1204,7 @@ export default {
let obj = JSON.parse(response.data.scenarioDefinition);
this.currentScenario.scenarioDefinition = obj;
this.currentScenario.name = response.data.name;
if (
this.currentScenario.scenarioDefinition &&
this.currentScenario.scenarioDefinition.hashTree
) {
if (this.currentScenario.scenarioDefinition && this.currentScenario.scenarioDefinition.hashTree) {
this.sort(this.currentScenario.scenarioDefinition.hashTree);
}
resolve();
@ -1361,14 +1233,8 @@ export default {
},
};
}
if (
stepArray[i] &&
stepArray[i].authManager &&
!stepArray[i].authManager.clazzName
) {
stepArray[i].authManager.clazzName = TYPE_TO_C.get(
stepArray[i].authManager.type
);
if (stepArray[i] && stepArray[i].authManager && !stepArray[i].authManager.clazzName) {
stepArray[i].authManager.clazzName = TYPE_TO_C.get(stepArray[i].authManager.type);
}
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
this.sort(stepArray[i].hashTree);
@ -1422,20 +1288,14 @@ export default {
hashTree: scenarioStep.hashTree,
};
if (this.currentScenario.environmentJson) {
this.projectEnvMap = objToStrMap(
JSON.parse(this.currentScenario.environmentJson)
);
this.projectEnvMap = objToStrMap(JSON.parse(this.currentScenario.environmentJson));
}
this.environmentType = this.currentScenario.environmentType;
this.envGroupId = this.currentScenario.environmentGroupId;
checkScenarioEnv(this.currentScenario.id).then((res) => {
let data = res.data;
if (!data) {
this.$warning(
this.$t(
'workspace.env_group.please_select_env_for_current_scenario'
)
);
this.$warning(this.$t('workspace.env_group.please_select_env_for_current_scenario'));
return false;
}
this.reportId = getUUID().substring(0, 8);
@ -1500,12 +1360,7 @@ export default {
this.hasRef = false;
checkBeforeDelete(param).then((response) => {
let checkResult = response.data;
let alertMsg =
this.$t('load_test.delete_threadgroup_confirm') +
'[' +
row.name +
']' +
'?';
let alertMsg = this.$t('load_test.delete_threadgroup_confirm') + '[' + row.name + ']' + '?';
if (checkResult.deleteFlag) {
alertMsg =
'[' +
@ -1513,16 +1368,10 @@ export default {
'] ' +
this.$t('api_definition.scenario_is') +
(checkResult.scenarioCount > 0
? this.$t('api_definition.scenario_count', [
checkResult.scenarioCount,
])
: '') +
(checkResult.planCount > 0 && checkResult.scenarioCount > 0
? '、 '
: '') +
(checkResult.planCount > 0
? this.$t('api_definition.plan_count', [checkResult.planCount])
? this.$t('api_definition.scenario_count', [checkResult.scenarioCount])
: '') +
(checkResult.planCount > 0 && checkResult.scenarioCount > 0 ? '、 ' : '') +
(checkResult.planCount > 0 ? this.$t('api_definition.plan_count', [checkResult.planCount]) : '') +
this.$t('api_test.scenario.reference') +
', ' +
this.$t('api_test.is_continue') +
@ -1531,20 +1380,11 @@ export default {
}
//
getScenarioVersions(row.id).then((response) => {
if (
hasLicense() &&
this.versionEnable &&
response.data.length > 1
) {
if (hasLicense() && this.versionEnable && response.data.length > 1) {
//
this.$refs.apiDeleteConfirmVersion.open(row, alertMsg);
} else {
this.$refs.apiDeleteConfirm.open(
alertMsg,
this.$t('permission.project_api_scenario.delete'),
row,
null
);
this.$refs.apiDeleteConfirm.open(alertMsg, this.$t('permission.project_api_scenario.delete'), row, null);
}
});
});
@ -1602,10 +1442,7 @@ export default {
this.result = false;
let obj = response.data;
obj.nodeTree = nodeTree;
downloadFile(
'Metersphere_Scenario_' + this.projectName + '.json',
JSON.stringify(obj)
);
downloadFile('Metersphere_Scenario_' + this.projectName + '.json', JSON.stringify(obj));
});
}
});
@ -1674,47 +1511,42 @@ export default {
this.$emit('selection', selection);
},
batchCreatePerformance() {
this.$alert(
this.$t('api_test.definition.request.batch_to_performance_confirm') +
' ',
'',
{
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
this.infoDb = false;
let param = {};
this.buildBatchParam(param);
batchGenPerformanceTestJmx(param).then((response) => {
let returnDTO = response.data;
let projectEnvMap = returnDTO.projectEnvMap;
let returnDataList = returnDTO.jmxInfoDTOList;
let jmxObjList = [];
returnDataList.forEach((item) => {
let jmxObj = {};
jmxObj.name = item.name;
jmxObj.xml = item.xml;
jmxObj.attachFiles = item.attachFiles;
jmxObj.attachByteFiles = item.attachByteFiles;
jmxObj.scenarioId = item.id;
jmxObj.version = item.version;
jmxObjList.push(jmxObj);
});
performanceStore.$patch({
scenarioJmxs: {
name: 'Scenarios',
jmxs: jmxObjList,
projectEnvMap: projectEnvMap,
},
});
this.$router.push({
path: '/performance/test/create',
});
this.$alert(this.$t('api_test.definition.request.batch_to_performance_confirm') + ' ', '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
this.infoDb = false;
let param = {};
this.buildBatchParam(param);
batchGenPerformanceTestJmx(param).then((response) => {
let returnDTO = response.data;
let projectEnvMap = returnDTO.projectEnvMap;
let returnDataList = returnDTO.jmxInfoDTOList;
let jmxObjList = [];
returnDataList.forEach((item) => {
let jmxObj = {};
jmxObj.name = item.name;
jmxObj.xml = item.xml;
jmxObj.attachFiles = item.attachFiles;
jmxObj.attachByteFiles = item.attachByteFiles;
jmxObj.scenarioId = item.id;
jmxObj.version = item.version;
jmxObjList.push(jmxObj);
});
}
},
}
);
performanceStore.$patch({
scenarioJmxs: {
name: 'Scenarios',
jmxs: jmxObjList,
projectEnvMap: projectEnvMap,
},
});
this.$router.push({
path: '/performance/test/create',
});
});
}
},
});
},
stop(row) {
execStop(this.reportId).then(() => {

View File

@ -21,35 +21,20 @@
@refresh="list"
@filter="filter"
@nodeSelectEvent="nodeChange"
ref="nodeTree"
>
ref="nodeTree">
<template v-slot:header>
<ms-search-bar
:show-operator="showOperator && !isTrashData"
:condition="condition"
:commands="operators"
/>
<ms-search-bar :show-operator="showOperator && !isTrashData" :condition="condition" :commands="operators" />
<module-trash-button
v-if="!isReadOnly && !isTrashData"
:condition="condition"
:exe="enableTrash"
:total="total"
/>
:total="total" />
</template>
</ms-node-tree>
<ms-add-basis-scenario
:module-options="data"
@saveAsEdit="saveAsEdit"
@refresh="refresh"
ref="basisScenario"
/>
<ms-add-basis-scenario :module-options="data" @saveAsEdit="saveAsEdit" @refresh="refresh" ref="basisScenario" />
<api-import
ref="apiImport"
:moduleOptions="data"
@refreshAll="$emit('refreshAll')"
/>
<api-import ref="apiImport" :moduleOptions="data" @refreshAll="$emit('refreshAll')" />
</div>
</template>
@ -199,21 +184,15 @@ export default {
},
list(projectId) {
if (this.isRelevanceModel) {
this.result = getModuleByRelevanceProjectId(
this.relevanceProjectId
).then((response) => {
this.result = getModuleByRelevanceProjectId(this.relevanceProjectId).then((response) => {
this.setData(response);
});
} else if (this.isTrashData) {
this.result = getModuleByTrash(
projectId ? projectId : this.projectId
).then((response) => {
this.result = getModuleByTrash(projectId ? projectId : this.projectId).then((response) => {
this.setData(response);
});
} else {
this.result = getModuleByProjectId(
projectId ? projectId : this.projectId
).then((response) => {
this.result = getModuleByProjectId(projectId ? projectId : this.projectId).then((response) => {
this.setData(response);
});
}
@ -222,10 +201,7 @@ export default {
if (response.data != undefined && response.data != null) {
this.data = response.data;
this.data.forEach((node) => {
node.name =
node.name === '未规划场景'
? this.$t('api_test.automation.unplanned_scenario')
: node.name;
node.name = node.name === '未规划场景' ? this.$t('api_test.automation.unplanned_scenario') : node.name;
buildTree(node, { path: '' });
});
this.$emit('setModuleOptions', this.data);
@ -304,11 +280,9 @@ export default {
//
nohupReloadTree(selectNodeId) {
if (this.isRelevanceModel) {
getModuleByRelevanceProjectId(this.relevanceProjectId).then(
(response) => {
this.setModuleList(response, selectNodeId);
}
);
getModuleByRelevanceProjectId(this.relevanceProjectId).then((response) => {
this.setModuleList(response, selectNodeId);
});
} else if (this.isTrashData) {
if (!this.projectId) {
return;
@ -329,10 +303,7 @@ export default {
if (response.data != undefined && response.data != null) {
this.data = response.data;
this.data.forEach((node) => {
node.name =
node.name === '未规划场景'
? this.$t('api_test.automation.unplanned_scenario')
: node.name;
node.name = node.name === '未规划场景' ? this.$t('api_test.automation.unplanned_scenario') : node.name;
buildTree(node, { path: '' });
});
@ -367,10 +338,7 @@ export default {
this.$emit('enableTrash', this.condition.trashEnable);
},
removeModuleId(nodeIds) {
if (
localStorage.getItem('scenarioModule') &&
localStorage.getItem('scenarioModule') === nodeIds[0]
) {
if (localStorage.getItem('scenarioModule') && localStorage.getItem('scenarioModule') === nodeIds[0]) {
localStorage.setItem('scenarioModule', undefined);
}
},

View File

@ -12,8 +12,7 @@
@change="change"
:value="item.uuid"
v-model="item.enable"
:disabled="isDisable(index) || isReadOnly"
/>
:disabled="isDisable(index) || isReadOnly" />
</el-col>
<el-col>
@ -26,8 +25,7 @@
maxlength="200"
@change="change"
:placeholder="$t('api_test.variable_name')"
show-word-limit
/>
show-word-limit />
</el-col>
<el-col>
<el-input
@ -36,8 +34,7 @@
size="small"
@change="change"
:placeholder="$t('api_test.value')"
show-word-limit
/>
show-word-limit />
</el-col>
<el-col class="kv-delete">
<el-button
@ -45,8 +42,7 @@
class="el-icon-delete-solid"
circle
@click="remove(index)"
:disabled="isDisable(index) || isReadOnly"
/>
:disabled="isDisable(index) || isReadOnly" />
</el-col>
</el-row>
</div>

View File

@ -7,13 +7,8 @@
v-bind="$attrs"
:size="size"
@change="change"
@input="input"
/>
<div
:class="{ hidden: !showVariable }"
class="variable-combine"
v-if="value"
>
@input="input" />
<div :class="{ hidden: !showVariable }" class="variable-combine" v-if="value">
<div v-if="showCopy" class="variable">{{ variable }}</div>
<el-tooltip
v-if="showCopy"
@ -21,8 +16,7 @@
manual
v-model="visible"
placement="top"
:visible-arrow="false"
>
:visible-arrow="false">
<i class="el-icon-copy-document copy" @click="copy" />
</el-tooltip>
</div>
@ -86,11 +80,7 @@ export default {
computed: {
variable() {
return (
'${' +
(this.showCopyTipWithMultiple ? this.value + '_n' : this.value) +
'}'
);
return '${' + (this.showCopyTipWithMultiple ? this.value + '_n' : this.value) + '}';
},
},
};

View File

@ -43,11 +43,7 @@ export default {
sort(stepArray) {
if (stepArray) {
for (let i in stepArray) {
if (
stepArray[i] &&
TYPE_TO_C.get(stepArray[i].type) &&
!stepArray[i].clazzName
) {
if (stepArray[i] && TYPE_TO_C.get(stepArray[i].type) && !stepArray[i].clazzName) {
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
}
if (stepArray[i].type === 'Assertions' && !stepArray[i].document) {
@ -61,14 +57,8 @@ export default {
},
};
}
if (
stepArray[i] &&
stepArray[i].authManager &&
!stepArray[i].authManager.clazzName
) {
stepArray[i].authManager.clazzName = TYPE_TO_C.get(
stepArray[i].authManager.type
);
if (stepArray[i] && stepArray[i].authManager && !stepArray[i].authManager.clazzName) {
stepArray[i].authManager.clazzName = TYPE_TO_C.get(stepArray[i].authManager.type);
}
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
this.sort(stepArray[i].hashTree);
@ -117,9 +107,7 @@ export default {
let url = '/api/automation/run/debug';
saveScenario(url, reqObj, this.runData.hashTree, this, (response) => {
if (response.data !== 'SUCCESS') {
this.$error(
response.data ? response.data : this.$t('commons.run_fail')
);
this.$error(response.data ? response.data : this.$t('commons.run_fail'));
this.$emit('errorRefresh');
}
});

View File

@ -5,25 +5,13 @@
v-model="envGroupId"
:placeholder="$t('workspace.env_group.select')"
style="margin-top: 8px; width: 200px"
size="small"
>
<el-option
v-for="(group, index) in groups"
:key="index"
:label="group.name"
:value="group.id"
/>
size="small">
<el-option v-for="(group, index) in groups" :key="index" :label="group.name" :value="group.id" />
</el-select>
<span style="margin-left: 8px">{{ $t('workspace.env_group.name') }}</span>
<i class="el-icon-view icon-view-btn" @click="viewGroup"></i>
</div>
<el-button
type="primary"
@click="handleConfirm"
size="small"
:style="btnStyle"
class="env-confirm"
>
<el-button type="primary" @click="handleConfirm" size="small" :style="btnStyle" class="env-confirm">
{{ $t('workspace.env_group.confirm') }}
</el-button>
<el-dialog
@ -31,14 +19,9 @@
append-to-body
:title="$t('workspace.env_group.name')"
@close="visible = false"
style="height: 800px"
>
style="height: 800px">
<template>
<environment-group
style="overflow-y: auto"
:screen-height="'350px'"
:read-only="true"
></environment-group>
<environment-group style="overflow-y: auto" :screen-height="'350px'" :read-only="true"></environment-group>
</template>
</el-dialog>
</div>
@ -46,10 +29,7 @@
<script>
import EnvironmentGroup from '@/business/commons/EnvironmentGroupList';
import {
environmentGetALL,
getEnvironmentMapByGroupId,
} from 'metersphere-frontend/src/api/environment';
import { environmentGetALL, getEnvironmentMapByGroupId } from 'metersphere-frontend/src/api/environment';
export default {
name: 'EnvGroup',
@ -121,9 +101,7 @@ export default {
let map = new Map(Object.entries(data));
for (let id of this.projectIds) {
if (!map.get(id)) {
this.$warning(
this.$t('workspace.env_group.lack_necessary_environment')
);
this.$warning(this.$t('workspace.env_group.lack_necessary_environment'));
resolve(false);
return;
}

View File

@ -6,32 +6,21 @@
:placeholder="$t('workspace.env_group.select')"
style="margin-top: 8px; width: 200px"
size="small"
clearable
>
<el-option-group
v-for="group in groups"
:key="group.label"
:label="group.label"
>
clearable>
<el-option-group v-for="group in groups" :key="group.label" :label="group.label">
<el-option
v-for="item in group.options"
:key="item.name"
:label="item.name"
:disabled="item.disabled"
:value="item.id"
>
:value="item.id">
</el-option>
</el-option-group>
</el-select>
<span style="margin-left: 8px">{{ $t('workspace.env_group.name') }}</span>
<i class="el-icon-view icon-view-btn" @click="viewGroup"></i>
</div>
<el-button
type="primary"
@click="handleConfirm"
size="small"
class="env-confirm"
>
<el-button type="primary" @click="handleConfirm" size="small" class="env-confirm">
{{ $t('workspace.env_group.confirm') }}
</el-button>
<el-dialog
@ -39,14 +28,9 @@
append-to-body
:title="$t('workspace.env_group.name')"
@close="visible = false"
style="height: 800px"
>
style="height: 800px">
<template>
<environment-group
style="overflow-y: auto"
:screen-height="'350px'"
:read-only="true"
></environment-group>
<environment-group style="overflow-y: auto" :screen-height="'350px'" :read-only="true"></environment-group>
</template>
</el-dialog>
</div>
@ -54,10 +38,7 @@
<script>
import EnvironmentGroup from '@/business/commons/EnvironmentGroupList';
import {
getEnvironmentMapByGroupId,
getEnvironmentOptions,
} from 'metersphere-frontend/src/api/environment';
import { getEnvironmentMapByGroupId, getEnvironmentOptions } from 'metersphere-frontend/src/api/environment';
export default {
name: 'EnvGroupWithOption',
@ -99,9 +80,7 @@ export default {
}).then((res) => {
let groups = res.data;
this.disabledGroups = groups.filter((group) => group.disabled === true);
this.notDisabledGroups = groups.filter(
(group) => group.disabled === false
);
this.notDisabledGroups = groups.filter((group) => group.disabled === false);
this.$set(this.groups, 0, {
label: this.$t('workspace.env_group.available_group'),
options: this.notDisabledGroups,
@ -139,9 +118,7 @@ export default {
let map = new Map(Object.entries(data));
for (let id of this.projectIds) {
if (!map.get(id)) {
this.$warning(
this.$t('workspace.env_group.lack_necessary_environment')
);
this.$warning(this.$t('workspace.env_group.lack_necessary_environment'));
resolve(false);
return;
}

View File

@ -5,34 +5,22 @@
:width="width"
:disabled="isReadOnly"
@show="showPopover"
trigger="click"
>
<el-radio-group
v-model="radio"
style="margin-left: 20px"
@change="radioChange"
>
<el-radio :label="ENV_TYPE.JSON">{{
$t('workspace.env_group.env_list')
}}</el-radio>
<el-radio v-if="showEnvGroup" :label="ENV_TYPE.GROUP">{{
$t('workspace.env_group.name')
}}</el-radio>
trigger="click">
<el-radio-group v-model="radio" style="margin-left: 20px" @change="radioChange">
<el-radio :label="ENV_TYPE.JSON">{{ $t('workspace.env_group.env_list') }}</el-radio>
<el-radio v-if="showEnvGroup" :label="ENV_TYPE.GROUP">{{ $t('workspace.env_group.name') }}</el-radio>
</el-radio-group>
<env-select
:project-ids="projectIds"
:result="result"
:show-config-button-with-out-permission="
showConfigButtonWithOutPermission
"
:show-config-button-with-out-permission="showConfigButtonWithOutPermission"
:env-map="envMap"
:project-list="projectList"
@close="visible = false"
@setProjectEnvMap="setProjectEnvMap"
v-show="!radio || radio === ENV_TYPE.JSON"
:btnStyle="btnStyle"
ref="envSelect"
/>
ref="envSelect" />
<env-group
ref="envGroup"
v-show="radio === ENV_TYPE.GROUP && !hasOptionGroup"
@ -40,8 +28,7 @@
:project-ids="projectIds"
@setEnvGroup="setEnvGroup"
:group-id="groupId"
:btnStyle="btnStyle"
></env-group>
:btnStyle="btnStyle"></env-group>
<!-- 对环境组选项进行分类 可用不可用 -->
<env-group-with-option
ref="envOptionGroup"
@ -49,14 +36,8 @@
@close="visible = false"
:project-ids="projectIds"
@setEnvGroup="setEnvGroup"
:group-id="groupId"
></env-group-with-option>
<el-button
type="primary"
slot="reference"
size="mini"
style="margin-top: 2px"
>
:group-id="groupId"></env-group-with-option>
<el-button type="primary" slot="reference" size="mini" style="margin-top: 2px">
{{ $t('api_test.definition.request.run_env') }}
<i class="el-icon-caret-bottom el-icon--right"></i>
</el-button>
@ -192,9 +173,7 @@ export default {
let res = this.$refs.envSelect.checkEnv(data);
resolve(res);
} else if (this.environmentType === ENV_TYPE.GROUP) {
let res = !this.hasOptionGroup
? this.$refs.envGroup.checkEnv()
: this.$refs.envOptionGroup.checkEnv();
let res = !this.hasOptionGroup ? this.$refs.envGroup.checkEnv() : this.$refs.envOptionGroup.checkEnv();
res.then((r) => {
resolve(r);
});

View File

@ -5,21 +5,18 @@
v-model="pe['selectEnv']"
:placeholder="$t('workspace.env_group.please_select_env')"
style="margin-top: 8px; width: 200px"
size="small"
>
size="small">
<el-option
v-for="(environment, index) in pe.envs"
:key="index"
:label="environment.name"
:value="environment.id"
/>
:value="environment.id" />
<el-button
class="ms-scenario-button"
v-if="isShowConfirmButton(pe.id)"
size="mini"
type="primary"
@click="openEnvironmentConfig(pe.id, pe['selectEnv'])"
>
@click="openEnvironmentConfig(pe.id, pe['selectEnv'])">
{{ $t('api_test.environment.environment_config') }}
</el-button>
<template v-slot:empty>
@ -28,8 +25,7 @@
class="ms-scenario-button"
size="mini"
type="primary"
@click="openEnvironmentConfig(pe.id, pe['selectEnv'])"
>
@click="openEnvironmentConfig(pe.id, pe['selectEnv'])">
{{ $t('api_test.environment.environment_config') }}
</el-button>
</div>
@ -40,21 +36,12 @@
</span>
</div>
<el-button
type="primary"
@click="handleConfirm"
size="small"
:style="btnStyle"
class="env-confirm"
>
<el-button type="primary" @click="handleConfirm" size="small" :style="btnStyle" class="env-confirm">
{{ $t('workspace.env_group.confirm') }}
</el-button>
<!-- 环境配置 -->
<api-environment-config
ref="environmentConfig"
@close="environmentConfigClose"
/>
<api-environment-config ref="environmentConfig" @close="environmentConfigClose" />
</div>
</template>
@ -142,8 +129,7 @@ export default {
envId = this.envMap.get(id);
}
//
temp.selectEnv =
envs.filter((e) => e.id === envId).length === 0 ? null : envId;
temp.selectEnv = envs.filter((e) => e.id === envId).length === 0 ? null : envId;
resolve();
});
});
@ -189,9 +175,7 @@ export default {
map.set(dt.id, dt.selectEnv);
});
if (!sign) {
this.$warning(
this.$t('workspace.env_group.please_select_env_for_current_scenario')
);
this.$warning(this.$t('workspace.env_group.please_select_env_for_current_scenario'));
return;
}
this.$emit('setProjectEnvMap', map);
@ -223,9 +207,7 @@ export default {
}
if (!sign) {
this.$warning(
this.$t('workspace.env_group.please_select_env_for_current_scenario')
);
this.$warning(this.$t('workspace.env_group.please_select_env_for_current_scenario'));
return false;
}
return true;

View File

@ -1,32 +1,20 @@
<template>
<div>
<div v-for="(pe, pIndex) in eventData" :key="pe.id">
<el-card
shadow="never"
style="margin-top: 8px; background: #f5f6f7; border-radius: 4px"
>
<el-card shadow="never" style="margin-top: 8px; background: #f5f6f7; border-radius: 4px">
<i
@click="expandCard(pIndex)"
v-if="pe.expendStatus === 'close'"
class="el-icon-caret-right"
style="color: var(--primary_color)"
/>
<i
@click="expandCard(pIndex)"
v-else
class="el-icon-caret-bottom"
style="color: var(--primary_color)"
/>
<span class="project-name" :title="getProjectName(pe.id)">
{{ getProjectName(pe.id) }} </span
><br />
style="color: var(--primary_color)" />
<i @click="expandCard(pIndex)" v-else class="el-icon-caret-bottom" style="color: var(--primary_color)" />
<span class="project-name" :title="getProjectName(pe.id)"> {{ getProjectName(pe.id) }} </span><br />
<div v-if="pe.expendStatus === 'open'">
<el-radio-group
v-model="pe.envRadio"
style="width: 100%"
@change="envRadioChange(pe.envRadio, pIndex)"
class="radio-change"
>
class="radio-change">
<el-radio label="DEFAULT_ENV" style="margin-top: 7px">{{
$t('api_test.environment.default_environment')
}}</el-radio>
@ -48,14 +36,12 @@
:placeholder="$t('api_test.environment.select_environment')"
style="margin-top: 8px; width: 100%"
size="small"
@change="chooseEnv"
>
@change="chooseEnv">
<el-option
v-for="(environment, index) in pe.envs"
:key="index"
:label="environment.name"
:value="environment.id"
/>
:value="environment.id" />
</el-select>
</div>
</el-card>
@ -121,8 +107,7 @@ export default {
},
envRadioChange(val, index) {
this.eventData[index].envRadio = val;
this.eventData[index].showEnvSelect =
this.eventData[index].envRadio === 'CUSTOMIZE_ENV';
this.eventData[index].showEnvSelect = this.eventData[index].envRadio === 'CUSTOMIZE_ENV';
},
viewGroup() {
this.visible = true;
@ -165,8 +150,7 @@ export default {
if (this.envMap && this.envMap.size > 0) {
let envId = this.envMap.get(id);
//
temp.selectEnv =
envs.filter((e) => e.id === envId).length === 0 ? null : envId;
temp.selectEnv = envs.filter((e) => e.id === envId).length === 0 ? null : envId;
}
if (this.isScenario) {
if (this.projectEnvMap) {

View File

@ -5,8 +5,7 @@
@selectModule="selectModule"
@getApiModuleTree="initTree"
@refresh="refresh"
@saveAsEdit="editScenario"
/>
@saveAsEdit="editScenario" />
</ms-aside-container>
<ms-main-container>
<ms-api-scenario-list
@ -15,19 +14,12 @@
@selection="setData"
:referenced="true"
:select-project-id="cuurentProjectId"
ref="apiScenarioList"
/>
ref="apiScenarioList" />
<el-button
style="float: right; margin: 10px"
@click="importApiScenario"
type="primary"
>
<el-button style="float: right; margin: 10px" @click="importApiScenario" type="primary">
{{ $t('api_test.scenario.reference') }}
</el-button>
<el-button style="float: right; margin: 10px" @click="copyApiScenario">{{
$t('commons.copy')
}}</el-button>
<el-button style="float: right; margin: 10px" @click="copyApiScenario">{{ $t('commons.copy') }}</el-button>
</ms-main-container>
</ms-container>
</template>
@ -92,28 +84,23 @@ export default {
},
getApiScenario() {
let scenarios = [];
this.result = getApiScenarios(this.currentScenarioIds).then(
(response) => {
if (response.data) {
response.data.forEach((item) => {
let scenarioDefinition = JSON.parse(item.scenarioDefinition);
let obj = {
id: item.id,
name: item.name,
type: 'scenario',
referenced: 'Copy',
resourceId: getUUID(),
hashTree:
scenarioDefinition && scenarioDefinition.hashTree
? scenarioDefinition.hashTree
: [],
};
scenarios.push(obj);
});
this.$emit('addScenario', scenarios);
}
this.result = getApiScenarios(this.currentScenarioIds).then((response) => {
if (response.data) {
response.data.forEach((item) => {
let scenarioDefinition = JSON.parse(item.scenarioDefinition);
let obj = {
id: item.id,
name: item.name,
type: 'scenario',
referenced: 'Copy',
resourceId: getUUID(),
hashTree: scenarioDefinition && scenarioDefinition.hashTree ? scenarioDefinition.hashTree : [],
};
scenarios.push(obj);
});
this.$emit('addScenario', scenarios);
}
);
});
},
copyApiScenario() {
if (this.currentScenarioIds) {

View File

@ -3,8 +3,7 @@
class="el-input-tag input-tag-wrapper"
:class="[size ? 'el-input-tag--' + size : '']"
style="height: auto"
@click="foucusTagInput"
>
@click="foucusTagInput">
<el-tag
class="ms-top"
v-for="(tag, idx) in innerTags"
@ -14,8 +13,7 @@
:size="size"
:closable="!readOnly"
:disable-transitions="false"
@close="remove(idx)"
>
@close="remove(idx)">
{{ tag && tag.length > 10 ? tag.substring(0, 10) + '...' : tag }}
</el-tag>
<input
@ -25,8 +23,7 @@
:placeholder="defaultPlaceHolder"
@keydown.delete.stop="removeLastTag"
@keydown="addNew"
@blur="addNew"
/>
@blur="addNew" />
</div>
</template>
@ -65,9 +62,7 @@ export default {
return {
defaultPlaceHolder: this.$t('commons.tag_tip'),
newTag: '',
innerTags: this.currentScenario[this.prop]
? [...this.currentScenario[this.prop]]
: [],
innerTags: this.currentScenario[this.prop] ? [...this.currentScenario[this.prop]] : [],
};
},
watch: {
@ -180,8 +175,7 @@ export default {
border: 0;
color: #303133;
font-size: 12px;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
outline: none;
padding-left: 0;
width: 100px;

View File

@ -1,20 +1,12 @@
<template>
<el-dialog
:title="title"
:visible.sync="deleteApiVisible"
:show-close="false"
width="30%"
>
<el-dialog :title="title" :visible.sync="deleteApiVisible" :show-close="false" width="30%">
<el-radio-group v-model="deleteCurrentVersion">
<el-radio :label="true">{{
$t('commons.delete_current_version')
}}</el-radio>
<el-radio :label="true">{{ $t('commons.delete_current_version') }}</el-radio>
<el-radio :label="false">{{ $t('commons.delete_all_version') }}</el-radio>
</el-radio-group>
<template v-slot:footer>
<ms-dialog-footer @cancel="close" @confirm="handleDelete">
</ms-dialog-footer>
<ms-dialog-footer @cancel="close" @confirm="handleDelete"> </ms-dialog-footer>
</template>
</el-dialog>
</template>

View File

@ -5,30 +5,20 @@
<el-icon class="el-icon-more"></el-icon>
</el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="ref">{{
$t('api_test.automation.view_ref')
}}</el-dropdown-item>
<el-dropdown-item
command="schedule"
v-permission="['PROJECT_API_SCENARIO:READ+SCHEDULE']"
>
<el-dropdown-item command="ref">{{ $t('api_test.automation.view_ref') }}</el-dropdown-item>
<el-dropdown-item command="schedule" v-permission="['PROJECT_API_SCENARIO:READ+SCHEDULE']">
{{ $t('api_test.automation.schedule') }}
</el-dropdown-item>
<el-dropdown-item
command="create_performance"
v-permission="['PROJECT_API_SCENARIO:READ+CREATE_PERFORMANCE']"
v-modules="['performance']"
>
v-modules="['performance']">
{{ $t('api_test.create_performance_test') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<ms-schedule-maintain
ref="scheduleMaintain"
@refreshTable="refreshTable"
:request="request"
/>
<ms-schedule-maintain ref="scheduleMaintain" @refreshTable="refreshTable" :request="request" />
</div>
</template>

View File

@ -67,10 +67,7 @@ export function STEP() {
'MsUiCommand',
],
],
[
'DEFINITION',
['HTTPSamplerProxy', 'DubboSampler', 'JDBCSampler', 'TCPSampler'],
],
['DEFINITION', ['HTTPSamplerProxy', 'DubboSampler', 'JDBCSampler', 'TCPSampler']],
[
'ALlSamplerStep',
[
@ -85,14 +82,7 @@ export function STEP() {
],
[
'AllCanExecType',
[
'HTTPSamplerProxy',
'DubboSampler',
'JDBCSampler',
'TCPSampler',
'JSR223Processor',
'AbstractSampler',
],
['HTTPSamplerProxy', 'DubboSampler', 'JDBCSampler', 'TCPSampler', 'JSR223Processor', 'AbstractSampler'],
],
]);
return map;
@ -120,81 +110,27 @@ export const ELEMENT_TYPE = {
export const TYPE_TO_C = new Map([
['scenario', 'io.metersphere.api.dto.definition.request.MsScenario'],
['UiScenario', 'io.metersphere.xpack.ui.hashtree.MsUiScenario'],
[
'HTTPSamplerProxy',
'io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy',
],
[
'DubboSampler',
'io.metersphere.api.dto.definition.request.sampler.MsDubboSampler',
],
[
'JDBCSampler',
'io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler',
],
[
'TCPSampler',
'io.metersphere.api.dto.definition.request.sampler.MsTCPSampler',
],
[
'IfController',
'io.metersphere.api.dto.definition.request.controller.MsIfController',
],
[
'TransactionController',
'io.metersphere.api.dto.definition.request.controller.MsTransactionController',
],
[
'LoopController',
'io.metersphere.api.dto.definition.request.controller.MsLoopController',
],
[
'ConstantTimer',
'io.metersphere.api.dto.definition.request.timer.MsConstantTimer',
],
[
'JSR223Processor',
'io.metersphere.api.dto.definition.request.processors.MsJSR223Processor',
],
[
'JSR223PreProcessor',
'io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor',
],
[
'JSR223PostProcessor',
'io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor',
],
[
'JDBCPreProcessor',
'io.metersphere.api.dto.definition.request.processors.pre.MsJDBCPreProcessor',
],
[
'JDBCPostProcessor',
'io.metersphere.api.dto.definition.request.processors.post.MsJDBCPostProcessor',
],
[
'Assertions',
'io.metersphere.api.dto.definition.request.assertions.MsAssertions',
],
['HTTPSamplerProxy', 'io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy'],
['DubboSampler', 'io.metersphere.api.dto.definition.request.sampler.MsDubboSampler'],
['JDBCSampler', 'io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler'],
['TCPSampler', 'io.metersphere.api.dto.definition.request.sampler.MsTCPSampler'],
['IfController', 'io.metersphere.api.dto.definition.request.controller.MsIfController'],
['TransactionController', 'io.metersphere.api.dto.definition.request.controller.MsTransactionController'],
['LoopController', 'io.metersphere.api.dto.definition.request.controller.MsLoopController'],
['ConstantTimer', 'io.metersphere.api.dto.definition.request.timer.MsConstantTimer'],
['JSR223Processor', 'io.metersphere.api.dto.definition.request.processors.MsJSR223Processor'],
['JSR223PreProcessor', 'io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor'],
['JSR223PostProcessor', 'io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor'],
['JDBCPreProcessor', 'io.metersphere.api.dto.definition.request.processors.pre.MsJDBCPreProcessor'],
['JDBCPostProcessor', 'io.metersphere.api.dto.definition.request.processors.post.MsJDBCPostProcessor'],
['Assertions', 'io.metersphere.api.dto.definition.request.assertions.MsAssertions'],
['Extract', 'io.metersphere.api.dto.definition.request.extract.MsExtract'],
[
'JmeterElement',
'io.metersphere.api.dto.definition.request.unknown.MsJmeterElement',
],
['JmeterElement', 'io.metersphere.api.dto.definition.request.unknown.MsJmeterElement'],
['TestPlan', 'io.metersphere.api.dto.definition.request.MsTestPlan'],
['ThreadGroup', 'io.metersphere.api.dto.definition.request.MsThreadGroup'],
[
'DNSCacheManager',
'io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager',
],
[
'DebugSampler',
'io.metersphere.api.dto.definition.request.sampler.MsDebugSampler',
],
[
'AuthManager',
'io.metersphere.api.dto.definition.request.auth.MsAuthManager',
],
['DNSCacheManager', 'io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager'],
['DebugSampler', 'io.metersphere.api.dto.definition.request.sampler.MsDebugSampler'],
['AuthManager', 'io.metersphere.api.dto.definition.request.auth.MsAuthManager'],
]);
export const PLUGIN_ELEMENTS = new Map([
@ -299,10 +235,7 @@ export const PLUGIN_ELEMENTS = new Map([
],
],
['menu_fragments', ['TestFragmentController']],
[
'menu_non_test_elements',
['ProxyControl', 'HttpMirrorControl', 'GenerateTree', 'PropertyControl'],
],
['menu_non_test_elements', ['ProxyControl', 'HttpMirrorControl', 'GenerateTree', 'PropertyControl']],
[
'menu_generative_controller',
[
@ -397,12 +330,7 @@ export function init() {
let allArray = [];
allArray = allArray.concat(PLUGIN_ELEMENTS.get('menu_generative_controller'));
allArray = allArray.concat(PLUGIN_ELEMENTS.get('menu_logic_controller'));
allArray = allArray.concat([
'scenario',
'ConstantTimer',
'JSR223Processor',
'Assertions',
]);
allArray = allArray.concat(['scenario', 'ConstantTimer', 'JSR223Processor', 'Assertions']);
return allArray;
}

View File

@ -5,11 +5,7 @@
<i class="el-icon-more ms-icon-more" />
</div>
<el-dropdown-menu slot="dropdown" class="dropdown-menu-class">
<el-dropdown-item
v-for="(btn, index) in buttons"
:key="index"
@click.native.stop="click(btn)"
>
<el-dropdown-item v-for="(btn, index) in buttons" :key="index" @click.native.stop="click(btn)">
{{ btn.name }}
</el-dropdown-item>
</el-dropdown-menu>

View File

@ -5,8 +5,7 @@
:visible.sync="httpVisible"
width="30%"
:destroy-on-close="true"
append-to-body
>
append-to-body>
<el-form
:model="httpForm"
label-position="right"
@ -14,25 +13,18 @@
size="small"
:rules="rule"
ref="httpForm"
v-if="!loading"
>
v-if="!loading">
<el-form-item :label="$t('api_definition.case_name')" prop="name">
<el-input
v-model="httpForm.name"
autocomplete="off"
:placeholder="$t('api_definition.case_name')"
show-word-limit
maxlength="100"
/>
maxlength="100" />
</el-form-item>
</el-form>
<template v-slot:footer>
<ms-dialog-footer
@cancel="httpVisible = false"
@confirm="saveApi"
v-prevent-re-click
>
</ms-dialog-footer>
<ms-dialog-footer @cancel="httpVisible = false" @confirm="saveApi" v-prevent-re-click> </ms-dialog-footer>
</template>
</el-dialog>
</template>

View File

@ -5,8 +5,7 @@
:visible.sync="httpVisible"
width="45%"
:destroy-on-close="true"
append-to-body
>
append-to-body>
<el-form
:model="httpForm"
label-position="right"
@ -14,61 +13,36 @@
size="small"
:rules="rule"
ref="httpForm"
v-if="!loading"
>
v-if="!loading">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input
v-model="httpForm.name"
autocomplete="off"
:placeholder="$t('commons.name')"
/>
<el-input v-model="httpForm.name" autocomplete="off" :placeholder="$t('commons.name')" />
</el-form-item>
<!--HTTP 协议特有参数-->
<el-form-item
:label="$t('api_report.request')"
prop="path"
v-if="currentProtocol === 'HTTP'"
>
<el-form-item :label="$t('api_report.request')" prop="path" v-if="currentProtocol === 'HTTP'">
<el-input
:placeholder="$t('api_test.definition.request.path_info')"
v-model="httpForm.path"
class="ms-http-input"
size="small"
>
<el-select
v-model="httpForm.method"
slot="prepend"
style="width: 100px"
size="small"
>
<el-option
v-for="item in options"
:key="item.id"
:label="item.label"
:value="item.id"
/>
size="small">
<el-select v-model="httpForm.method" slot="prepend" style="width: 100px" size="small">
<el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
</el-input>
</el-form-item>
<el-form-item
:label="$t('api_test.definition.request.responsible')"
prop="userId"
>
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
<el-select
v-model="httpForm.userId"
:placeholder="$t('api_test.definition.request.responsible')"
filterable
size="small"
style="width: 100%"
>
style="width: 100%">
<el-option
v-for="item in maintainerOptions"
:key="item.id"
:label="item.id + ' (' + item.name + ')'"
:value="item.id"
>
:value="item.id">
</el-option>
</el-select>
</el-form-item>
@ -80,23 +54,17 @@
@getValue="setModule"
:obj="moduleObj"
clearable
checkStrictly
/>
checkStrictly />
</el-form-item>
<el-form-item
:label="$t('commons.description')"
prop="description"
style="margin-bottom: 29px"
>
<el-form-item :label="$t('commons.description')" prop="description" style="margin-bottom: 29px">
<el-input
class="ms-http-textarea"
v-model="httpForm.description"
type="textarea"
:autosize="{ minRows: 2, maxRows: 10 }"
:rows="2"
size="small"
/>
size="small" />
</el-form-item>
<el-form-item class="create-tip">
{{ $t('api_test.definition.create_tip') }}
@ -104,12 +72,7 @@
</el-form>
<template v-slot:footer>
<ms-dialog-footer
@cancel="httpVisible = false"
@confirm="saveApi"
v-prevent-re-click
>
</ms-dialog-footer>
<ms-dialog-footer @cancel="httpVisible = false" @confirm="saveApi" v-prevent-re-click> </ms-dialog-footer>
</template>
</el-dialog>
</template>
@ -121,14 +84,8 @@ import { getApiModules } from '@/api/definition-module';
import { getMaintainer } from '@/api/project';
import MsDialogFooter from 'metersphere-frontend/src/components/MsDialogFooter';
import { REQ_METHOD } from '@/business/definition/model/JsonData';
import {
getCurrentProjectID,
getCurrentUser,
} from 'metersphere-frontend/src/utils/token';
import {
createComponent,
Request,
} from '@/business/definition/components/jmeter/components';
import { getCurrentProjectID, getCurrentUser } from 'metersphere-frontend/src/utils/token';
import { createComponent, Request } from '@/business/definition/components/jmeter/components';
import { getUUID } from 'metersphere-frontend/src/utils';
import MsSelectTree from 'metersphere-frontend/src/components/select-tree/SelectTree';
import { buildTree } from 'metersphere-frontend/src/model/NodeTree';
@ -324,10 +281,7 @@ export default {
this.httpForm.request.path = this.httpForm.path;
}
if (this.currentModule != null) {
this.httpForm.modulePath =
this.currentModule.method != undefined
? this.currentModule.method
: null;
this.httpForm.modulePath = this.currentModule.method != undefined ? this.currentModule.method : null;
this.httpForm.moduleId = this.currentModule.id;
}
},
@ -357,16 +311,14 @@ export default {
if (data.protocol === 'dubbo://') {
data.protocol = 'DUBBO';
}
this.result = getApiModules(getCurrentProjectID(), data.protocol).then(
(response) => {
if (response.data != undefined && response.data != null) {
this.moduleOptions = response.data;
this.moduleOptions.forEach((node) => {
buildTree(node, { path: '' });
});
}
this.result = getApiModules(getCurrentProjectID(), data.protocol).then((response) => {
if (response.data != undefined && response.data != null) {
this.moduleOptions = response.data;
this.moduleOptions.forEach((node) => {
buildTree(node, { path: '' });
});
}
);
});
},
setModule(id, data) {
this.httpForm.moduleId = id;

View File

@ -3,8 +3,7 @@
:is-across-space="isAcrossSpace"
@setProject="setProject"
:dialog-title="$t('api_test.definition.api_import')"
ref="baseRelevance"
>
ref="baseRelevance">
<template v-slot:aside>
<ms-api-module
@nodeSelectEvent="nodeChange"
@ -14,8 +13,7 @@
:is-relevance="true"
:is-read-only="true"
:select-project-id="projectId"
ref="nodeTree"
/>
ref="nodeTree" />
</template>
<scenario-relevance-api-list
@ -28,15 +26,13 @@
:is-api-list-enable="isApiListEnable"
@isApiListEnableChange="isApiListEnableChange"
@selectCountChange="setSelectCounts"
ref="apiList"
>
ref="apiList">
<template v-slot:version>
<mx-version-select
v-xpack
:project-id="projectId"
:default-version="currentVersion"
@changeVersion="currentVersionChange"
/>
@changeVersion="currentVersionChange" />
</template>
</scenario-relevance-api-list>
@ -50,33 +46,22 @@
:is-api-list-enable="isApiListEnable"
@isApiListEnableChange="isApiListEnableChange"
@selectCountChange="setSelectCounts"
ref="apiCaseList"
>
ref="apiCaseList">
<template v-slot:version>
<mx-version-select
v-xpack
:project-id="projectId"
:default-version="currentVersion"
@changeVersion="currentVersionChange"
/>
@changeVersion="currentVersionChange" />
</template>
</scenario-relevance-case-list>
<template v-slot:headerBtn>
<!-- 显示数量 -->
<table-select-count-bar
:count="selectCounts"
style="float: left; margin: 5px"
/>
<table-select-count-bar :count="selectCounts" style="float: left; margin: 5px" />
<el-button size="mini" icon="el-icon-refresh" @click="refresh" />
<el-button
type="primary"
@click="copy"
:loading="buttonIsWorking"
@keydown.enter.native.prevent
size="mini"
>
<el-button type="primary" @click="copy" :loading="buttonIsWorking" @keydown.enter.native.prevent size="mini">
{{ $t('commons.copy') }}
</el-button>
<el-button
@ -85,8 +70,7 @@
:loading="buttonIsWorking"
@click="reference"
size="mini"
@keydown.enter.native.prevent
>
@keydown.enter.native.prevent>
{{ $t('api_test.scenario.reference') }}
</el-button>
</template>
@ -111,8 +95,7 @@ import TableSelectCountBar from '@/business/automation/scenario/api/TableSelectC
export default {
name: 'ApiRelevance',
components: {
MxVersionSelect: () =>
import('metersphere-frontend/src/components/version/MxVersionSelect'),
MxVersionSelect: () => import('metersphere-frontend/src/components/version/MxVersionSelect'),
TableSelectCountBar,
TestCaseRelevanceBase,
RelevanceDialog,

View File

@ -1,9 +1,6 @@
<template>
<div v-loading="result">
<api-list-container
:is-api-list-enable="isApiListEnable"
@isApiListEnableChange="isApiListEnableChange"
>
<api-list-container :is-api-list-enable="isApiListEnable" @isApiListEnableChange="isApiListEnableChange">
<template>
<slot name="version"></slot>
</template>
@ -22,16 +19,14 @@
@setSelectRow="setSelectRow"
@selectCountChange="selectCountChange"
@refreshTable="initTable"
ref="apitable"
>
ref="apitable">
<template v-slot:header>
<ms-environment-select
:project-id="projectId"
v-if="isTestPlan || isScript"
:is-read-only="isReadOnly"
@setEnvironment="setEnvironment"
ref="msEnvironmentSelect"
/>
ref="msEnvironmentSelect" />
</template>
</api-table-list>
</api-list-container>
@ -39,10 +34,7 @@
</template>
<script>
import {
getDefinitionPage,
getRelevanceDefinitionPage,
} from '@/api/definition';
import { getDefinitionPage, getRelevanceDefinitionPage } from '@/api/definition';
import ApiListContainer from '@/business/definition/components/list/ApiListContainer';
import MsEnvironmentSelect from '@/business/definition/components/case/MsEnvironmentSelect';
import { buildBatchParam } from 'metersphere-frontend/src/utils/tableUtils';

View File

@ -1,9 +1,6 @@
<template>
<div v-loading="result">
<api-list-container
:is-api-list-enable="isApiListEnable"
@isApiListEnableChange="isApiListEnableChange"
>
<api-list-container :is-api-list-enable="isApiListEnable" @isApiListEnableChange="isApiListEnableChange">
<template>
<slot name="version"></slot>
</template>
@ -13,8 +10,7 @@
v-if="isTestPlan || isScript"
:is-read-only="isReadOnly"
@setEnvironment="setEnvironment"
ref="msEnvironmentSelect"
/>
ref="msEnvironmentSelect" />
<ms-search :condition.sync="condition" @search="initTable"> </ms-search>
<ms-table
:data="tableData"
@ -27,24 +23,17 @@
@refresh="initTable"
@selectCountChange="selectCountChange"
operator-width="170px"
ref="table"
>
<ms-table-column prop="num" label="ID" width="80px" sortable="true">
</ms-table-column>
ref="table">
<ms-table-column prop="num" label="ID" width="80px" sortable="true"> </ms-table-column>
<ms-table-column
prop="name"
width="160px"
:label="$t('test_track.case.name')"
/>
<ms-table-column prop="name" width="160px" :label="$t('test_track.case.name')" />
<ms-table-column
prop="priority"
:filters="priorityFilters"
column-key="priority"
width="120px"
:label="$t('test_track.case.priority')"
>
:label="$t('test_track.case.priority')">
<template v-slot:default="scope">
<priority-table-item :value="scope.row.priority" />
</template>
@ -54,8 +43,7 @@
sortable="custom"
prop="path"
width="180px"
:label="'API' + $t('api_test.definition.api_path')"
/>
:label="'API' + $t('api_test.definition.api_path')" />
<ms-table-column prop="tags" width="120px" :label="$t('commons.tag')">
<template v-slot:default="scope">
@ -65,8 +53,7 @@
type="success"
effect="plain"
:content="itemName"
style="margin-left: 0px; margin-right: 2px"
/>
style="margin-left: 0px; margin-right: 2px" />
</template>
</ms-table-column>
@ -75,8 +62,7 @@
:label="$t('project.version.name')"
:filters="versionFilters"
min-width="100px"
prop="versionId"
>
prop="versionId">
<template v-slot:default="scope">
<span>{{ scope.row.versionName }}</span>
</template>
@ -84,12 +70,7 @@
<ms-table-column prop="createUser" :label="$t('commons.create_user')" />
<ms-table-column
sortable="createTime"
width="160px"
:label="$t('commons.create_time')"
prop="createTime"
>
<ms-table-column sortable="createTime" width="160px" :label="$t('commons.create_time')" prop="createTime">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | datetimeFormat }}</span>
</template>
@ -99,8 +80,7 @@
sortable="updateTime"
width="160px"
:label="$t('api_test.definition.api_last_time')"
prop="updateTime"
>
prop="updateTime">
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | datetimeFormat }}</span>
</template>
@ -110,8 +90,7 @@
:change="initTable"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:total="total"
/>
:total="total" />
</api-list-container>
</div>
</template>
@ -129,18 +108,11 @@ import MsTag from 'metersphere-frontend/src/components/MsTag';
import MsBottomContainer from '@/business/definition/components/BottomContainer';
import ShowMoreBtn from '@/business/commons/ShowMoreBtn';
import MsBatchEdit from '@/business/definition/components/basis/BatchEdit';
import {
API_METHOD_COLOUR,
CASE_PRIORITY,
} from '@/business/definition/model/JsonData';
import { API_METHOD_COLOUR, CASE_PRIORITY } from '@/business/definition/model/JsonData';
import ApiListContainer from '@/business/definition/components/list/ApiListContainer';
import PriorityTableItem from '@/business/commons/PriorityTableItem';
import MsEnvironmentSelect from '@/business/definition/components/case/MsEnvironmentSelect';
import {
_filter,
_sort,
buildBatchParam,
} from 'metersphere-frontend/src/utils/tableUtils';
import { _filter, _sort, buildBatchParam } from 'metersphere-frontend/src/utils/tableUtils';
import MsTableAdvSearchBar from 'metersphere-frontend/src/components/search/MsTableAdvSearchBar';
import { TEST_PLAN_RELEVANCE_API_CASE_CONFIGS } from 'metersphere-frontend/src/components/search/search-components';
import { hasLicense } from 'metersphere-frontend/src/utils/permission';
@ -276,11 +248,7 @@ export default {
this.condition.protocol = this.currentProtocol;
}
this.condition.ids = [];
this.result = apiTestCasePage(
this.currentPage,
this.pageSize,
this.condition
).then((response) => {
this.result = apiTestCasePage(this.currentPage, this.pageSize, this.condition).then((response) => {
this.setData(response);
});
},

View File

@ -3,16 +3,14 @@
<ms-search
:base-search-tip="$t('api_test.definition.request.select_case')"
:condition.sync="condition"
@search="search"
>
@search="search">
</ms-search>
<mx-version-select
v-xpack
:project-id="projectId"
@changeVersion="changeVersion"
style="float: left"
class="search-input"
/>
class="search-input" />
<ms-table
ref="scenarioTable"
@ -26,53 +24,27 @@
:row-order-group-id="projectId"
@refresh="search"
:disable-header-config="true"
@selectCountChange="selectCountChange"
>
<el-table-column
v-if="!customNum"
prop="num"
label="ID"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
v-if="customNum"
prop="customNum"
label="ID"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="name"
:label="$t('api_test.automation.scenario_name')"
show-overflow-tooltip
/>
@selectCountChange="selectCountChange">
<el-table-column v-if="!customNum" prop="num" label="ID" show-overflow-tooltip> </el-table-column>
<el-table-column v-if="customNum" prop="customNum" label="ID" show-overflow-tooltip> </el-table-column>
<el-table-column prop="name" :label="$t('api_test.automation.scenario_name')" show-overflow-tooltip />
<el-table-column
v-if="versionEnable"
column-key="version_id"
:filters="versionFilters"
:label="$t('commons.version')"
min-width="120px"
>
min-width="120px">
<template v-slot:default="scope">
<span>{{ scope.row.versionName }}</span>
</template>
</el-table-column>
<el-table-column
prop="level"
:label="$t('api_test.automation.case_level')"
show-overflow-tooltip
>
<el-table-column prop="level" :label="$t('api_test.automation.case_level')" show-overflow-tooltip>
<template v-slot:default="scope">
<priority-table-item :value="scope.row.level" ref="level" />
</template>
</el-table-column>
<el-table-column
prop="tagNames"
:label="$t('api_test.automation.tag')"
min-width="120"
>
<el-table-column prop="tagNames" :label="$t('api_test.automation.tag')" min-width="120">
<template v-slot:default="scope">
<ms-tag
v-for="itemName in scope.row.tags"
@ -80,62 +52,29 @@
type="success"
effect="plain"
:content="itemName"
style="margin-left: 0px; margin-right: 2px"
/>
style="margin-left: 0px; margin-right: 2px" />
</template>
</el-table-column>
<el-table-column
prop="userId"
:label="$t('api_test.automation.creator')"
show-overflow-tooltip
/>
<el-table-column
prop="updateTime"
:label="$t('api_test.automation.update_time')"
width="180"
>
<el-table-column prop="userId" :label="$t('api_test.automation.creator')" show-overflow-tooltip />
<el-table-column prop="updateTime" :label="$t('api_test.automation.update_time')" width="180">
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | datetimeFormat }}</span>
</template>
</el-table-column>
<el-table-column
prop="stepTotal"
:label="$t('api_test.automation.step')"
show-overflow-tooltip
/>
<el-table-column
prop="lastResult"
:label="$t('api_test.automation.last_result')"
>
<el-table-column prop="stepTotal" :label="$t('api_test.automation.step')" show-overflow-tooltip />
<el-table-column prop="lastResult" :label="$t('api_test.automation.last_result')">
<template v-slot:default="{ row }">
<el-link
type="success"
@click="showReport(row)"
v-if="row.lastResult === 'SUCCESS'"
>
<el-link type="success" @click="showReport(row)" v-if="row.lastResult === 'SUCCESS'">
{{ $t('api_test.automation.success') }}
</el-link>
<el-link
type="danger"
@click="showReport(row)"
v-if="row.lastResult === 'ERROR'"
>
<el-link type="danger" @click="showReport(row)" v-if="row.lastResult === 'ERROR'">
{{ $t('api_test.automation.fail') }}
</el-link>
</template>
</el-table-column>
<el-table-column
prop="passRate"
:label="$t('api_test.automation.passing_rate')"
show-overflow-tooltip
/>
<el-table-column prop="passRate" :label="$t('api_test.automation.passing_rate')" show-overflow-tooltip />
</ms-table>
<ms-table-pagination
:change="search"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:total="total"
/>
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total" />
</div>
</template>
@ -171,8 +110,7 @@ export default {
MsApiReportDetail,
MsTableAdvSearchBar,
MsSearch,
MxVersionSelect: () =>
import('metersphere-frontend/src/components/version/MxVersionSelect'),
MxVersionSelect: () => import('metersphere-frontend/src/components/version/MxVersionSelect'),
},
props: {
referenced: {
@ -247,11 +185,7 @@ export default {
}
if (this.condition.projectId) {
this.result = getScenarioList(
this.currentPage,
this.pageSize,
this.condition
).then((response) => {
this.result = getScenarioList(this.currentPage, this.pageSize, this.condition).then((response) => {
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
@ -288,9 +222,7 @@ export default {
}
},
getConditions() {
this.condition.tableDataIds = Array.from(this.tableData).map(
(row) => row.id
);
this.condition.tableDataIds = Array.from(this.tableData).map((row) => row.id);
return this.condition;
},
checkEnv() {

View File

@ -4,8 +4,7 @@
:dialog-title="$t('api_test.automation.scenario_import')"
@setProject="setProject"
@refreshNode="refresh"
ref="baseRelevance"
>
ref="baseRelevance">
<template v-slot:aside>
<ms-api-scenario-module
style="margin-top: 5px"
@ -15,8 +14,7 @@
@enableTrash="false"
:is-read-only="true"
:select-project-id="projectId"
ref="nodeTree"
/>
ref="nodeTree" />
</template>
<relevance-scenario-list
@ -26,33 +24,17 @@
:referenced="true"
:trash-enable="false"
@selectCountChange="setSelectCounts"
ref="apiScenarioList"
>
ref="apiScenarioList">
</relevance-scenario-list>
<template v-slot:headerBtn>
<table-select-count-bar
:count="selectCounts"
style="float: left; margin: 5px"
/>
<table-select-count-bar :count="selectCounts" style="float: left; margin: 5px" />
<el-button size="mini" icon="el-icon-refresh" @click="refresh" />
<el-button
type="primary"
@click="copy"
:loading="buttonIsWorking"
@keydown.enter.native.prevent
size="mini"
>
<el-button type="primary" @click="copy" :loading="buttonIsWorking" @keydown.enter.native.prevent size="mini">
{{ $t('commons.copy') }}
</el-button>
<el-button
type="primary"
@click="reference"
:loading="buttonIsWorking"
@keydown.enter.native.prevent
size="mini"
>
<el-button type="primary" @click="reference" :loading="buttonIsWorking" @keydown.enter.native.prevent size="mini">
{{ $t('api_test.scenario.reference') }}
</el-button>
</template>
@ -161,15 +143,8 @@ export default {
});
if (emptyStepScenarios !== '') {
if (emptyStepScenarios.endsWith(',')) {
emptyStepScenarios = emptyStepScenarios.substring(
0,
emptyStepScenarios.length - 1
);
this.$error(
this.$t('api_test.scenario.scenario_step_is_empty', [
emptyStepScenarios,
])
);
emptyStepScenarios = emptyStepScenarios.substring(0, emptyStepScenarios.length - 1);
this.$error(this.$t('api_test.scenario.scenario_step_is_empty', [emptyStepScenarios]));
}
}
},
@ -178,10 +153,7 @@ export default {
let scenarios = [];
let conditions = this.getConditions();
this.currentScenarioIds.sort((a, b) => {
return (
conditions.tableDataIds.indexOf(a) -
conditions.tableDataIds.indexOf(b)
);
return conditions.tableDataIds.indexOf(a) - conditions.tableDataIds.indexOf(b);
});
if (conditions.selectAll) {
let params = {};
@ -190,10 +162,7 @@ export default {
apiScenarioAll(params).then(
(response) => {
this.currentScenarioIds = response.data;
if (
!this.currentScenarioIds ||
this.currentScenarioIds.length < 1
) {
if (!this.currentScenarioIds || this.currentScenarioIds.length < 1) {
this.$warning('请选择场景');
this.buttonIsWorking = false;
return;
@ -201,11 +170,7 @@ export default {
this.result = getApiScenarios(this.currentScenarioIds).then(
(response) => {
if (response.data) {
this.createScenarioDefinition(
scenarios,
response.data,
referenced
);
this.createScenarioDefinition(scenarios, response.data, referenced);
this.$emit('save', scenarios);
this.$refs.baseRelevance.close();
this.buttonIsWorking = false;
@ -230,11 +195,7 @@ export default {
(response) => {
if (response.data) {
this.currentScenarioIds = [];
this.createScenarioDefinition(
scenarios,
response.data,
referenced
);
this.createScenarioDefinition(scenarios, response.data, referenced);
this.$emit('save', scenarios);
this.$refs.baseRelevance.close();
this.buttonIsWorking = false;

View File

@ -5,16 +5,12 @@
<div
v-if="data.index"
class="el-step__icon is-text"
:style="{ color: color, 'background-color': backgroundColor }"
>
:style="{ color: color, 'background-color': backgroundColor }">
<div class="el-step__icon-inner" :key="forceRerenderIndex">
{{ data.index }}
</div>
</div>
<el-tag
class="ms-left-btn"
size="small"
:style="{ color: color, 'background-color': backgroundColor }"
<el-tag class="ms-left-btn" size="small" :style="{ color: color, 'background-color': backgroundColor }"
>{{ title }}
</el-tag>
<slot name="behindHeaderLeft" v-if="!isMax"></slot>
@ -27,8 +23,7 @@
:class="{ 'is-active': data.active }"
@click="active(data)"
v-if="data.type != 'scenario' && !isMax"
@click.stop
/>
@click.stop />
<span @click.stop v-if="isShowInput && isShowNameInput">
<el-input
:draggable="draggable"
@ -39,8 +34,7 @@
@blur="isShowInput = false"
:placeholder="$t('commons.input_name')"
ref="nameEdit"
:disabled="data.disabled"
/>
:disabled="data.disabled" />
</span>
<span
@ -48,21 +42,16 @@
id="moveout"
@mouseenter="enter($event)"
@mouseleave="leave($event)"
v-else
>
v-else>
<i
class="el-icon-edit"
style="cursor: pointer"
@click="editName"
v-show="data.referenced != 'REF' && !data.disabled"
/>
v-show="data.referenced != 'REF' && !data.disabled" />
<span>{{ data.name }}</span>
<el-tag
size="mini"
v-if="data.method && !data.pluginId"
style="margin-left: 1rem"
>{{ getMethod() }}</el-tag
>
<el-tag size="mini" v-if="data.method && !data.pluginId" style="margin-left: 1rem">{{
getMethod()
}}</el-tag>
<slot name="afterTitle" />
</span>
</slot>
@ -81,24 +70,18 @@
'PROJECT_API_SCENARIO:READ+EDIT',
'PROJECT_API_SCENARIO:READ+CREATE',
'PROJECT_API_SCENARIO:READ+COPY',
]"
>
]">
<slot name="message" v-show="!isMax"></slot>
<slot name="debugStepCode"></slot>
<slot name="button" v-if="showVersion"></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.refEnable || !showVersion || isDeleted"
/>
:disabled="data.refEnable || !showVersion || isDeleted" />
</el-tooltip>
<el-button
@ -108,8 +91,7 @@
circle
@click="copyRow"
style="padding: 5px"
:disabled="(data.disabled && !data.root) || !showVersion || isDeleted"
/>
:disabled="(data.disabled && !data.root) || !showVersion || isDeleted" />
<el-button
v-show="isSingleButton"
@ -119,8 +101,7 @@
style="padding: 5px"
circle
@click="remove"
:disabled="(data.disabled && !data.root) || !showVersion || isDeleted"
/>
:disabled="(data.disabled && !data.root) || !showVersion || isDeleted" />
<step-extend-btns
style="display: contents"
@ -133,8 +114,7 @@
@copy="copyRow"
@remove="remove"
@openScenario="openScenario"
v-show="isMoreButton"
/>
v-show="isMoreButton" />
</div>
</div>
<!--最大化不显示具体内容-->
@ -245,10 +225,7 @@ export default {
},
watch: {
selectStep() {
if (
store.selectStep &&
store.selectStep.resourceId === this.data.resourceId
) {
if (store.selectStep && store.selectStep.resourceId === this.data.resourceId) {
this.colorStyle = this.color;
} else {
this.colorStyle = '';
@ -264,10 +241,7 @@ export default {
this.$refs.nameEdit.focus();
});
}
if (
this.data &&
this.stepFilter.get('AllSamplerProxy').indexOf(this.data.type) != -1
) {
if (this.data && this.stepFilter.get('AllSamplerProxy').indexOf(this.data.type) != -1) {
if (!this.data.method) {
this.data.method = this.data.protocol;
}
@ -281,33 +255,21 @@ export default {
return store.forceRerenderIndex;
},
isSingleButton() {
if (
this.data.type === 'ConstantTimer' ||
this.data.type === 'Assertions'
) {
if (this.data.type === 'ConstantTimer' || this.data.type === 'Assertions') {
return (
this.innerStep &&
this.showVersion &&
this.stepFilter.get('ALlSamplerStep').indexOf(this.data.type) !== -1
this.innerStep && this.showVersion && this.stepFilter.get('ALlSamplerStep').indexOf(this.data.type) !== -1
);
}
return (
this.showVersion &&
this.stepFilter.get('ALlSamplerStep').indexOf(this.data.type) !== -1
);
return this.showVersion && this.stepFilter.get('ALlSamplerStep').indexOf(this.data.type) !== -1;
},
isMoreButton() {
if (
this.data.type === 'ConstantTimer' ||
this.data.type === 'Assertions'
) {
if (this.data.type === 'ConstantTimer' || this.data.type === 'Assertions') {
return (
!this.innerStep ||
(this.showBtn &&
(!this.data.disabled || this.data.root) &&
this.showVersion &&
this.stepFilter.get('ALlSamplerStep').indexOf(this.data.type) ===
-1)
this.stepFilter.get('ALlSamplerStep').indexOf(this.data.type) === -1)
);
}
return (

View File

@ -4,8 +4,7 @@
:title="$t('load_test.runtime_config')"
width="550px"
@close="close"
:visible.sync="runModeVisible"
>
:visible.sync="runModeVisible">
<div class="env-container">
<div>
<div>{{ $t('commons.environment') }}</div>
@ -19,8 +18,7 @@
@setProjectEnvMap="setProjectEnvMap"
@setEnvGroup="setEnvGroup"
ref="envSelectPopover"
class="mode-row"
></env-select-popover>
class="mode-row"></env-select-popover>
</div>
<div>
@ -30,8 +28,7 @@
v-model="runConfig.mode"
@change="changeMode"
style="width: 100%"
class="radio-change mode-row"
>
class="radio-change mode-row">
<el-radio label="serial">{{ $t('run_mode.serial') }}</el-radio>
<el-radio label="parallel">{{ $t('run_mode.parallel') }}</el-radio>
</el-radio-group>
@ -42,19 +39,11 @@
<div class="mode-row">{{ $t('run_mode.other_config') }}</div>
<div class="mode-row">
<el-radio-group v-model="runConfig.reportType">
<el-radio label="iddReport">{{
$t('run_mode.idd_report')
}}</el-radio>
<el-radio label="setReport">{{
$t('run_mode.set_report')
}}</el-radio>
<el-radio label="iddReport">{{ $t('run_mode.idd_report') }}</el-radio>
<el-radio label="setReport">{{ $t('run_mode.set_report') }}</el-radio>
</el-radio-group>
</div>
<div
class="ms-mode-span-label"
style="margin-top: 8px"
v-if="runConfig.reportType === 'setReport'"
>
<div class="ms-mode-span-label" style="margin-top: 8px" v-if="runConfig.reportType === 'setReport'">
{{ $t('run_mode.report_name') }}
</div>
<div class="mode-row" v-if="runConfig.reportType === 'setReport'">
@ -62,14 +51,10 @@
v-model="runConfig.reportName"
:placeholder="$t('commons.input_content')"
size="small"
style="width: 100%"
/>
style="width: 100%" />
</div>
<div class="mode-row">
<el-checkbox
v-model="runConfig.runWithinResourcePool"
:disabled="runMode === 'POOL'"
>
<el-checkbox v-model="runConfig.runWithinResourcePool" :disabled="runMode === 'POOL'">
{{ $t('run_mode.run_with_resource_pool') }} </el-checkbox
><br />
<el-select
@ -77,15 +62,13 @@
v-model="runConfig.resourcePoolId"
size="mini"
class="mode-row"
style="width: 100%"
>
style="width: 100%">
<el-option
v-for="item in resourcePools"
:key="item.id"
:label="item.name"
:disabled="!item.api"
:value="item.id"
>
:value="item.id">
</el-option>
</el-select>
</div>
@ -199,21 +182,15 @@ export default {
},
handleRunBatch() {
if (
(this.runConfig.mode === 'serial' ||
this.runConfig.mode === 'parallel') &&
(this.runConfig.mode === 'serial' || this.runConfig.mode === 'parallel') &&
this.runConfig.reportType === 'setReport' &&
this.runConfig.reportName.trim() === ''
) {
this.$warning(this.$t('commons.input_name'));
return;
}
if (
this.runConfig.runWithinResourcePool &&
this.runConfig.resourcePoolId == null
) {
this.$warning(
this.$t('workspace.env_group.please_select_run_within_resource_pool')
);
if (this.runConfig.runWithinResourcePool && this.runConfig.resourcePoolId == null) {
this.$warning(this.$t('workspace.env_group.please_select_run_within_resource_pool'));
return;
}
this.$emit('handleRunBatch', this.runConfig);

View File

@ -2,26 +2,15 @@
<div>
<div v-if="request.protocol === 'HTTP'">
<div v-if="isCustomizeReq">
<el-select
v-model="request.method"
class="ms-select"
size="small"
:disabled="request.disabled"
>
<el-option
v-for="item in reqOptions"
:key="item.id"
:label="item.label"
:value="item.id"
/>
<el-select v-model="request.method" class="ms-select" size="small" :disabled="request.disabled">
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
<el-input
v-model="request.domain"
v-if="request.isRefEnvironment && request.domain"
size="small"
readonly
class="ms-input"
/>
class="ms-input" />
<el-input
:placeholder="$t('api_test.definition.request.path_all_info')"
@ -30,8 +19,7 @@
size="small"
@blur="urlChange"
:disabled="request.disabled"
v-if="request.isRefEnvironment"
/>
v-if="request.isRefEnvironment" />
<el-input
:placeholder="$t('api_test.definition.request.path_all_info')"
@ -40,31 +28,19 @@
size="small"
@blur="urlChange"
:disabled="request.disabled"
v-else
/>
v-else />
<el-checkbox
v-if="isCustomizeReq"
class="is-ref-environment"
v-model="request.isRefEnvironment"
@change="setDomain"
:disabled="request.disabled"
>
:disabled="request.disabled">
{{ $t('api_test.request.refer_to_environment') }}
</el-checkbox>
</div>
<div v-else>
<el-select
v-model="request.method"
class="ms-select"
size="small"
:disabled="request.disabled"
>
<el-option
v-for="item in reqOptions"
:key="item.id"
:label="item.label"
:value="item.id"
/>
<el-select v-model="request.method" class="ms-select" size="small" :disabled="request.disabled">
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
<el-input
v-model="request.domain"
@ -72,16 +48,14 @@
size="small"
readonly
class="ms-input"
:disabled="request.disabled"
/>
:disabled="request.disabled" />
<el-input
:placeholder="$t('api_test.definition.request.path_all_info')"
style="width: 50%"
v-model="request.path"
size="small"
@blur="pathChange"
:disabled="request.disabled"
/>
:disabled="request.disabled" />
</div>
</div>
@ -89,25 +63,12 @@
<el-form>
<el-row>
<el-col :span="8">
<el-form-item
:label="$t('api_test.request.tcp.server')"
prop="server"
>
<el-input
class="server-input"
v-model="request.server"
maxlength="300"
show-word-limit
size="small"
/>
<el-form-item :label="$t('api_test.request.tcp.server')" prop="server">
<el-input class="server-input" v-model="request.server" maxlength="300" show-word-limit size="small" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="$t('api_test.request.tcp.port')"
prop="port"
label-width="60px"
>
<el-form-item :label="$t('api_test.request.tcp.port')" prop="port" label-width="60px">
<el-input v-model="request.port" size="small" />
</el-form-item>
</el-col>
@ -136,9 +97,7 @@ export default {
if (!this.request.path || this.request.path.indexOf('?') === -1) return;
let url = this.getURL(this.addProtocol(this.request.path));
if (url) {
this.request.path = decodeURIComponent(
this.request.path.substr(0, this.request.path.indexOf('?'))
);
this.request.path = decodeURIComponent(this.request.path.substr(0, this.request.path.indexOf('?')));
}
},
urlChange() {
@ -149,23 +108,16 @@ export default {
if (!this.request.url || this.request.url.indexOf('?') === -1) return;
let url = this.getURL(this.addProtocol(this.request.url));
if (url) {
let paramUrl = this.request.url.substr(
this.request.url.indexOf('?') + 1
);
let paramUrl = this.request.url.substr(this.request.url.indexOf('?') + 1);
if (paramUrl) {
this.request.url = decodeURIComponent(
this.request.url.substr(0, this.request.url.indexOf('?'))
);
this.request.url = decodeURIComponent(this.request.url.substr(0, this.request.url.indexOf('?')));
}
}
}
},
addProtocol(url) {
if (url) {
if (
!url.toLowerCase().startsWith('https') &&
!url.toLowerCase().startsWith('http')
) {
if (!url.toLowerCase().startsWith('https') && !url.toLowerCase().startsWith('http')) {
return 'https://' + url;
}
}

View File

@ -7,14 +7,10 @@
ref="request"
label-width="100px"
:disabled="request.disabled"
style="margin: 10px"
>
style="margin: 10px">
<el-row>
<el-col :span="8">
<el-form-item
prop="environmentId"
:label="$t('api_test.definition.request.run_env')"
>
<el-form-item prop="environmentId" :label="$t('api_test.definition.request.run_env')">
<el-select
v-model="request.environmentId"
size="small"
@ -22,30 +18,18 @@
:placeholder="$t('api_test.definition.request.run_env')"
@change="environmentChange"
clearable
:disabled="isReadOnly"
>
:disabled="isReadOnly">
<el-option
v-for="(environment, index) in environments"
:key="index"
:label="environment.name"
:value="environment.id"
/>
<el-button
class="environment-button"
size="small"
type="primary"
@click="openEnvironmentConfig"
>
:value="environment.id" />
<el-button class="environment-button" size="small" type="primary" @click="openEnvironmentConfig">
{{ $t('api_test.environment.environment_config') }}
</el-button>
<template v-slot:empty>
<div class="empty-environment">
<el-button
class="environment-button"
size="small"
type="primary"
@click="openEnvironmentConfig"
>
<el-button class="environment-button" size="small" type="primary" @click="openEnvironmentConfig">
{{ $t('api_test.environment.environment_config') }}
</el-button>
</div>
@ -54,83 +38,45 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
:label="$t('api_test.request.sql.dataSource')"
prop="dataSourceId"
style="margin-left: 10px"
>
<el-select
v-model="request.dataSourceId"
size="small"
@change="reload"
:disabled="request.disabled"
>
<el-form-item :label="$t('api_test.request.sql.dataSource')" prop="dataSourceId" style="margin-left: 10px">
<el-select v-model="request.dataSourceId" size="small" @change="reload" :disabled="request.disabled">
<el-option
v-for="(item, index) in databaseConfigsOptions"
:key="index"
:value="item.id"
:label="item.name"
/>
:label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
:label="$t('api_test.request.sql.timeout')"
prop="queryTimeout"
style="margin-left: 10px"
>
<el-form-item :label="$t('api_test.request.sql.timeout')" prop="queryTimeout" style="margin-left: 10px">
<el-input-number
:disabled="request.disabled"
size="small"
v-model="request.queryTimeout"
:placeholder="$t('commons.millisecond')"
:max="1000 * 10000000"
:min="0"
/>
:min="0" />
</el-form-item>
</el-col>
</el-row>
<el-form-item
:label="$t('api_test.request.sql.result_variable')"
prop="resultVariable"
>
<el-input
v-model="request.resultVariable"
maxlength="500"
show-word-limit
size="small"
/>
<el-form-item :label="$t('api_test.request.sql.result_variable')" prop="resultVariable">
<el-input v-model="request.resultVariable" maxlength="500" show-word-limit size="small" />
</el-form-item>
<el-form-item
:label="$t('api_test.request.sql.variable_names')"
prop="variableNames"
>
<el-input
v-model="request.variableNames"
maxlength="500"
show-word-limit
size="small"
/>
<el-form-item :label="$t('api_test.request.sql.variable_names')" prop="variableNames">
<el-input v-model="request.variableNames" maxlength="500" show-word-limit size="small" />
</el-form-item>
<el-tabs v-model="activeName" class="ms-sql-tabs">
<el-tab-pane
:label="$t('api_test.scenario.variables')"
name="variables"
>
<el-tab-pane :label="$t('api_test.scenario.variables')" name="variables">
<ms-api-scenario-variables
:is-read-only="isReadOnly"
:items="request.variables"
:description="$t('api_test.scenario.kv_description')"
/>
:description="$t('api_test.scenario.kv_description')" />
</el-tab-pane>
<el-tab-pane
:label="$t('api_test.request.sql.sql_script')"
name="sql"
>
<el-tab-pane :label="$t('api_test.request.sql.sql_script')" name="sql">
<ms-code-edit
:height="120"
:read-only="isReadOnly"
@ -138,18 +84,14 @@
:data.sync="request.query"
theme="eclipse"
mode="sql"
ref="codeEdit"
/>
ref="codeEdit" />
</el-tab-pane>
</el-tabs>
</el-form>
</div>
<!-- 环境 -->
<api-environment-config
ref="environmentConfig"
@close="environmentConfigClose"
/>
<api-environment-config ref="environmentConfig" @close="environmentConfigClose" />
</div>
</template>
@ -296,13 +238,8 @@ export default {
getEnvironments(environmentId) {
let envId = '';
let id = this.request.projectId ? this.request.projectId : this.projectId;
let scenarioEnvId =
this.scenarioId !== '' ? this.scenarioId + '_' + id : id;
if (
store.scenarioEnvMap &&
store.scenarioEnvMap instanceof Map &&
store.scenarioEnvMap.has(scenarioEnvId)
) {
let scenarioEnvId = this.scenarioId !== '' ? this.scenarioId + '_' + id : id;
if (store.scenarioEnvMap && store.scenarioEnvMap instanceof Map && store.scenarioEnvMap.has(scenarioEnvId)) {
envId = store.scenarioEnvMap.get(scenarioEnvId);
}
if (!this.scenarioId && !this.request.customizeReq) {
@ -317,23 +254,15 @@ export default {
.match(/\[object (\w+)\]/)[1]
.toLowerCase();
if (obj !== 'object' && obj !== 'map') {
this.request.refEevMap = objToStrMap(
JSON.parse(this.request.refEevMap)
);
this.request.refEevMap = objToStrMap(JSON.parse(this.request.refEevMap));
} else if (obj === 'object' && obj !== 'map') {
this.request.refEevMap = objToStrMap(this.request.refEevMap);
}
if (
this.request.refEevMap instanceof Map &&
this.request.refEevMap.has(id)
) {
if (this.request.refEevMap instanceof Map && this.request.refEevMap.has(id)) {
envId = this.request.refEevMap.get(id);
}
}
if (
envId === this.request.originalEnvironmentId &&
this.request.originalDataSourceId
) {
if (envId === this.request.originalEnvironmentId && this.request.originalDataSourceId) {
this.request.dataSourceId = this.request.originalDataSourceId;
}
let targetDataSourceName = '';
@ -343,10 +272,7 @@ export default {
this.environments.forEach((environment) => {
parseEnvironment(environment);
//
if (
environment.id === this.request.environmentId &&
environment.id !== envId
) {
if (environment.id === this.request.environmentId && environment.id !== envId) {
if (environment.config && environment.config.databaseConfigs) {
environment.config.databaseConfigs.forEach((item) => {
if (item.id === this.request.dataSourceId) {
@ -367,13 +293,9 @@ export default {
this.$refs.environmentConfig.open(getCurrentProjectID());
},
setStep(envId, currentEnvironment, targetDataSourceName) {
let envs = this.environments.filter(
(item) => this.request && item.id === this.request.environmentId
);
let envs = this.environments.filter((item) => this.request && item.id === this.request.environmentId);
if (envs && envs.length === 0) {
let id = this.request.projectId
? this.request.projectId
: this.projectId;
let id = this.request.projectId ? this.request.projectId : this.projectId;
this.result = getEnvironmentByProjectId(id).then((response) => {
this.environments = response.data;
this.environments.forEach((environment) => {
@ -398,11 +320,7 @@ export default {
}
}
let flag = false;
if (
currentEnvironment &&
currentEnvironment.config &&
currentEnvironment.config.databaseConfigs
) {
if (currentEnvironment && currentEnvironment.config && currentEnvironment.config.databaseConfigs) {
currentEnvironment.config.databaseConfigs.forEach((item) => {
if (item.id === this.request.dataSourceId) {
flag = true;
@ -415,8 +333,7 @@ export default {
this.databaseConfigsOptions.push(item);
});
if (!flag && currentEnvironment.config.databaseConfigs.length > 0) {
this.request.dataSourceId =
currentEnvironment.config.databaseConfigs[0].id;
this.request.dataSourceId = currentEnvironment.config.databaseConfigs[0].id;
flag = true;
}
}

View File

@ -9,20 +9,14 @@
:data.sync="jsr223ProcessorData.script"
theme="eclipse"
:modes="['java', 'python']"
ref="codeEdit"
/>
ref="codeEdit" />
</el-col>
<div style="width: 14px; margin-right: 5px">
<div style="height: 12px; width: 12px; line-height: 12px">
<i
:class="
showMenu
? 'el-icon-remove-outline'
: 'el-icon-circle-plus-outline'
"
:class="showMenu ? 'el-icon-remove-outline' : 'el-icon-circle-plus-outline'"
class="show-menu"
@click="switchMenu"
></i>
@click="switchMenu"></i>
</div>
</div>
<el-col :span="menuSpan" class="script-index" v-if="isReadOnly !== true">
@ -30,14 +24,12 @@
:default-command="jsr223ProcessorData.scriptLanguage"
:commands="languages"
style="margin-bottom: 5px; margin-left: 15px"
@command="languageChange"
/>
@command="languageChange" />
<script-nav-menu
ref="scriptNavMenu"
:language="jsr223ProcessorData.scriptLanguage"
:menus="codeTemplates"
@handleCode="handleCodeTemplate"
/>
@handleCode="handleCodeTemplate" />
</el-col>
</el-row>
</div>
@ -72,35 +64,25 @@ export default {
title: this.$t('project.code_segment.custom_value'),
children: [
{
title: this.$t(
'api_test.request.processor.code_template_get_variable'
),
title: this.$t('api_test.request.processor.code_template_get_variable'),
value: 'vars.get("variable_name")',
},
{
title: this.$t(
'api_test.request.processor.code_template_set_variable'
),
title: this.$t('api_test.request.processor.code_template_set_variable'),
value: 'vars.put("variable_name", "variable_value")',
},
{
title: this.$t(
'api_test.request.processor.code_template_get_response_header'
),
title: this.$t('api_test.request.processor.code_template_get_response_header'),
value: 'prev.getResponseHeaders()',
disabled: this.isPreProcessor,
},
{
title: this.$t(
'api_test.request.processor.code_template_get_response_code'
),
title: this.$t('api_test.request.processor.code_template_get_response_code'),
value: 'prev.getResponseCode()',
disabled: this.isPreProcessor,
},
{
title: this.$t(
'api_test.request.processor.code_template_get_response_result'
),
title: this.$t('api_test.request.processor.code_template_get_response_result'),
value: 'prev.getResponseDataAsString()',
disabled: this.isPreProcessor,
},
@ -110,12 +92,8 @@ export default {
title: this.$t('project.code_segment.project_env'),
children: [
{
title: this.$t(
'api_test.request.processor.param_environment_set_global_variable'
),
value:
'vars.put(${__metersphere_env_id}+"key","value");\n' +
'vars.put("key","value")',
title: this.$t('api_test.request.processor.param_environment_set_global_variable'),
value: 'vars.put(${__metersphere_env_id}+"key","value");\n' + 'vars.put("key","value")',
},
],
},
@ -133,8 +111,7 @@ export default {
children: [
{
title: this.$t('project.code_segment.stop_test'),
value:
'ctx.getEngine().stopThreadNow(ctx.getThread().getThreadName());',
value: 'ctx.getEngine().stopThreadNow(ctx.getThread().getThreadName());',
},
],
},
@ -143,9 +120,7 @@ export default {
hideScript: this.isHideScript(),
children: [
{
title: this.$t(
'api_test.request.processor.code_add_report_length'
),
title: this.$t('api_test.request.processor.code_add_report_length'),
value:
'String report = ctx.getCurrentSampler().getRequestData();\n' +
'if(report!=null){\n' +
@ -156,9 +131,7 @@ export default {
'}',
},
{
title: this.$t(
'api_test.request.processor.code_hide_report_length'
),
title: this.$t('api_test.request.processor.code_hide_report_length'),
value:
'//Get response data\n' +
'String returnData = prev.getResponseDataAsString();\n' +

View File

@ -8,19 +8,14 @@
:beforeUpload="uploadValidate"
:file-list="plugin.files"
:on-exceed="exceed"
ref="upload"
>
ref="upload">
<div class="upload-default">
<i class="el-icon-plus" />
</div>
<div class="upload-item" slot="file" slot-scope="{ file }">
<span>{{ file.file ? file.file.name : file.name }}</span>
<span class="el-upload-list__item-actions">
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete" />
</span>
</span>
@ -54,9 +49,7 @@ export default {
this.$refs.upload.handleRemove(file);
for (let i = 0; i < this.plugin.files.length; i++) {
let fileName = file.file ? file.file.name : file.name;
let paramFileName = this.plugin.files[i].file
? this.plugin.files[i].file.name
: this.plugin.files[i].name;
let paramFileName = this.plugin.files[i].file ? this.plugin.files[i].file.name : this.plugin.files[i].name;
if (fileName === paramFileName) {
this.plugin.files.splice(i, 1);
this.$refs.upload.handleRemove(file);

View File

@ -6,41 +6,24 @@
:visible.sync="visible"
class="api-import"
v-loading="result"
@close="close"
>
@close="close">
<div class="header-bar">
<div>{{ $t('api_test.api_import.data_format') }}</div>
<el-radio-group v-model="selectedPlatformValue">
<el-radio
v-for="(item, index) in platforms"
:key="index"
:label="item.value"
>{{ item.name }}</el-radio
>
<el-radio v-for="(item, index) in platforms" :key="index" :label="item.value">{{ item.name }}</el-radio>
</el-radio-group>
<div class="operate-button">
<el-button class="save-button" type="primary" plain @click="save">
{{ $t('commons.save') }}
</el-button>
<el-button
class="cancel-button"
type="warning"
plain
@click="visible = false"
>
<el-button class="cancel-button" type="warning" plain @click="visible = false">
{{ $t('commons.cancel') }}
</el-button>
</div>
</div>
<el-form
:model="formData"
:rules="rules"
label-width="105px"
v-loading="result"
ref="form"
>
<el-form :model="formData" :rules="rules" label-width="105px" v-loading="result" ref="form">
<el-row>
<el-col :span="11">
<el-form-item :label="$t('commons.import_module')">
@ -51,91 +34,41 @@
@getValue="setModule"
:obj="moduleObj"
clearable
checkStrictly
/>
checkStrictly />
</el-form-item>
<el-form-item :label="$t('commons.import_mode')" prop="modeId">
<el-select
size="small"
v-model="formData.modeId"
class="project-select"
clearable
>
<el-option
v-for="item in modeOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-select size="small" v-model="formData.modeId" class="project-select" clearable>
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-checkbox
size="mini"
v-if="formData.modeId === 'fullCoverage'"
v-model="formData.coverModule"
>
<el-checkbox size="mini" v-if="formData.modeId === 'fullCoverage'" v-model="formData.coverModule">
{{ this.$t('commons.cover_scenario') }}
</el-checkbox>
</el-form-item>
<el-form-item
v-xpack
v-if="
projectVersionEnable && formData.modeId === 'incrementalMerge'
"
v-if="projectVersionEnable && formData.modeId === 'incrementalMerge'"
:label="$t('api_test.api_import.import_version')"
prop="versionId"
>
<el-select
size="small"
v-model="formData.versionId"
clearable
style="width: 100%"
>
<el-option
v-for="item in versionOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
prop="versionId">
<el-select size="small" v-model="formData.versionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item
v-xpack
v-if="projectVersionEnable && formData.modeId === 'fullCoverage'"
:label="$t('api_test.api_import.data_update_version')"
prop="versionId"
>
<el-select
size="small"
v-model="formData.updateVersionId"
clearable
style="width: 100%"
>
<el-option
v-for="item in versionOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
prop="versionId">
<el-select size="small" v-model="formData.updateVersionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item
v-xpack
v-if="projectVersionEnable && formData.modeId === 'fullCoverage'"
:label="$t('api_test.api_import.data_new_version')"
prop="versionId"
>
<el-select
size="small"
v-model="formData.versionId"
clearable
style="width: 100%"
>
<el-option
v-for="item in versionOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
prop="versionId">
<el-select size="small" v-model="formData.versionId" clearable style="width: 100%">
<el-option v-for="item in versionOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
@ -153,13 +86,9 @@
:on-remove="handleRemove"
:file-list="fileList"
:on-exceed="handleExceed"
multiple
>
multiple>
<i class="el-icon-upload"></i>
<div
class="el-upload__text"
v-html="$t('load_test.upload_tips')"
></div>
<div class="el-upload__text" v-html="$t('load_test.upload_tips')"></div>
<div class="el-upload__tip" slot="tip">
{{ $t('api_test.api_import.file_size_limit') }}
</div>
@ -170,16 +99,10 @@
<div class="format-tip">
<div>
<span
>{{ $t('api_test.api_import.tip') }}{{ selectedPlatform.tip }}</span
>
<span>{{ $t('api_test.api_import.tip') }}{{ selectedPlatform.tip }}</span>
</div>
<div>
<span
>{{ $t('api_test.api_import.export_tip') }}{{
selectedPlatform.exportTip
}}</span
>
<span>{{ $t('api_test.api_import.export_tip') }}{{ selectedPlatform.exportTip }}</span>
</div>
<div>
<span>
@ -203,10 +126,7 @@ import { importScenario } from '@/api/scenario';
import MsDialogFooter from 'metersphere-frontend/src/components/MsDialogFooter';
import { getCurrentProjectID } from 'metersphere-frontend/src/utils/token';
import { hasLicense } from 'metersphere-frontend/src/utils/permission';
import {
listenGoBack,
removeGoBackListener,
} from 'metersphere-frontend/src/utils';
import { listenGoBack, removeGoBackListener } from 'metersphere-frontend/src/utils';
import MsSelectTree from 'metersphere-frontend/src/components/select-tree/SelectTree';
export default {
@ -351,10 +271,7 @@ export default {
},
uploadValidate(file, fileList) {
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
if (
this.selectedPlatform.suffixes &&
!this.selectedPlatform.suffixes.has(suffix)
) {
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
@ -370,30 +287,22 @@ export default {
this.$warning('请添加一个文件');
return;
}
let suffix = this.formData.file.name.substring(
this.formData.file.name.lastIndexOf('.') + 1
);
if (
this.selectedPlatform.suffixes &&
!this.selectedPlatform.suffixes.has(suffix)
) {
let suffix = this.formData.file.name.substring(this.formData.file.name.lastIndexOf('.') + 1);
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
return false;
}
this.$refs.form.validate((valid) => {
if (valid) {
let param = this.buildParam();
this.result = importScenario(
'/api/automation/import',
param.file,
null,
this.buildParam()
).then((response) => {
let res = response.data;
this.$success(this.$t('test_track.case.import.success'));
this.visible = false;
this.$emit('refreshAll', res);
});
this.result = importScenario('/api/automation/import', param.file, null, this.buildParam()).then(
(response) => {
let res = response.data;
this.$success(this.$t('test_track.case.import.success'));
this.visible = false;
this.$emit('refreshAll', res);
}
);
} else {
return false;
}
@ -442,13 +351,10 @@ export default {
getVersionOptions() {
if (hasLicense()) {
getProjectVersions(getCurrentProjectID()).then((response) => {
this.versionOptions = response.data.filter(
(v) => v.status === 'open'
);
this.versionOptions = response.data.filter((v) => v.status === 'open');
this.versionOptions.forEach((v) => {
if (v.latest) {
v.name =
v.name + ' ' + this.$t('api_test.api_import.latest_version');
v.name = v.name + ' ' + this.$t('api_test.api_import.latest_version');
}
});
});

View File

@ -4,8 +4,7 @@
@save="save"
:plan-id="planId"
:dialog-title="dialogTitle"
ref="baseRelevance"
>
ref="baseRelevance">
<template v-slot:aside>
<ms-api-module
:options="options"
@ -15,8 +14,7 @@
@refreshTable="refresh"
@setModuleOptions="setModuleOptions"
:is-read-only="true"
ref="nodeTree"
/>
ref="nodeTree" />
</template>
<relevance-api-list
@ -29,8 +27,7 @@
:is-script="isScript"
:plan-id="planId"
@isApiListEnableChange="isApiListEnableChange"
ref="apiList"
/>
ref="apiList" />
<relevance-case-list
v-if="!isApiListEnable"
@ -42,8 +39,7 @@
:is-script="isScript"
:plan-id="planId"
@isApiListEnableChange="isApiListEnableChange"
ref="apiCaseList"
/>
ref="apiCaseList" />
</test-case-relevance-base>
</template>
@ -101,9 +97,7 @@ export default {
created() {
if (this.isScript) {
if (this.isApiListEnable) {
this.dialogTitle = this.$t(
'permission.project_api_definition.import_api'
);
this.dialogTitle = this.$t('permission.project_api_definition.import_api');
} else {
this.dialogTitle = this.$t('permission.project_track_case.import');
}
@ -116,9 +110,7 @@ export default {
isApiListEnable() {
if (this.isScript) {
if (this.isApiListEnable) {
this.dialogTitle = this.$t(
'permission.project_api_definition.import_api'
);
this.dialogTitle = this.$t('permission.project_api_definition.import_api');
} else {
this.dialogTitle = this.$t('permission.project_track_case.import');
}

View File

@ -9,23 +9,20 @@
top="10vh"
v-loading="result"
append-to-body
class="customFunc"
>
class="customFunc">
<div>
<el-alert
:title="$t('project.code_segment.relate_tip')"
type="info"
style="width: 350px; float: left"
:closable="false"
show-icon
>
show-icon>
</el-alert>
<ms-table-search-bar
:condition.sync="condition"
@change="init"
class="search-bar"
:tip="$t('project.code_segment.search')"
/>
:tip="$t('project.code_segment.search')" />
<el-table
border
class="adjust-table"
@ -33,18 +30,9 @@
style="width: 100%"
ref="table"
highlight-current-row
@current-change="handleCurrentChange"
>
<el-table-column
prop="name"
:label="$t('commons.name')"
show-overflow-tooltip
/>
<el-table-column
prop="description"
:label="$t('commons.description')"
show-overflow-tooltip
>
@current-change="handleCurrentChange">
<el-table-column prop="name" :label="$t('commons.name')" show-overflow-tooltip />
<el-table-column prop="description" :label="$t('commons.description')" show-overflow-tooltip>
<template v-slot:default="scope">
<pre>{{ scope.row.description }}</pre>
</template>
@ -57,45 +45,24 @@
type="success"
effect="plain"
:content="itemName"
style="margin-left: 0; margin-right: 2px"
>
style="margin-left: 0; margin-right: 2px">
</ms-tag>
<span></span>
</template>
</el-table-column>
<el-table-column
prop="type"
:label="$t('project.code_segment.language')"
show-overflow-tooltip
/>
<el-table-column
prop="createTime"
:label="$t('commons.create_time')"
show-overflow-tooltip
>
<el-table-column prop="type" :label="$t('project.code_segment.language')" show-overflow-tooltip />
<el-table-column prop="createTime" :label="$t('commons.create_time')" show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.createTime | datetimeFormat }}</span>
</template>
</el-table-column>
</el-table>
<ms-table-pagination
:change="init"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:total="total"
/>
<ms-table-pagination :change="init" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total" />
</div>
<template v-slot:footer>
<el-button @click="close" size="medium">{{
$t('commons.cancel')
}}</el-button>
<el-button
type="primary"
@click="submit"
size="medium"
style="margin-left: 10px"
>
<el-button @click="close" size="medium">{{ $t('commons.cancel') }}</el-button>
<el-button type="primary" @click="submit" size="medium" style="margin-left: 10px">
{{ $t('commons.confirm') }}
</el-button>
</template>
@ -139,11 +106,7 @@ export default {
this.condition.type = language;
}
this.condition.projectId = getCurrentProjectID();
this.result = funcList(
this.currentPage,
this.pageSize,
this.condition
).then((res) => {
this.result = funcList(this.currentPage, this.pageSize, this.condition).then((res) => {
let tableData = res.data;
const { itemCount, listObject } = tableData;
this.total = itemCount;
@ -186,8 +149,7 @@ export default {
<style scoped>
pre {
margin: 0 0;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
}
.search-bar {

View File

@ -1,17 +1,13 @@
<template>
<div style="line-height: 20px">
<div class="template-title">
<span class="nav-font">{{
$t('api_test.request.processor.code_template')
}}</span>
<span class="nav-font">{{ $t('api_test.request.processor.code_template') }}</span>
<el-link
href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor"
target="componentReferenceDoc"
style="margin-left: 30px; margin-bottom: 3px"
type="primary"
><span style="font-size: 13px">{{
$t('commons.reference_documentation')
}}</span>
><span style="font-size: 13px">{{ $t('commons.reference_documentation') }}</span>
</el-link>
</div>
<div v-for="(menu, index) in menus" :key="index">
@ -20,43 +16,28 @@
class="icon el-icon-arrow-right"
style="font-weight: bold; margin-right: 2px"
@click="active(menu)"
:class="{ 'is-active': menu.open }"
></i>
<span @click="active(menu)" class="nav-menu-title nav-font">{{
menu.title
}}</span>
:class="{ 'is-active': menu.open }"></i>
<span @click="active(menu)" class="nav-menu-title nav-font">{{ menu.title }}</span>
</span>
<el-collapse-transition>
<div v-if="menu.open">
<div
v-for="(child, key) in menu.children"
:key="key"
class="func-div"
>
<el-link
:disabled="child.disabled"
@click="handleClick(child)"
class="func-link nav-font"
>
<div v-for="(child, key) in menu.children" :key="key" class="func-div">
<el-link :disabled="child.disabled" @click="handleClick(child)" class="func-link nav-font">
{{ child.title }}
</el-link>
</div>
</div>
</el-collapse-transition>
</div>
<custom-function-relate
ref="customFunctionRelate"
@addCustomFuncScript="handleCodeTemplate"
/>
<custom-function-relate ref="customFunctionRelate" @addCustomFuncScript="handleCodeTemplate" />
<!--接口列表-->
<api-func-relevance
@save="apiSave"
:is-test-plan="false"
:is-script="true"
@close="apiClose"
ref="apiFuncRelevance"
/>
ref="apiFuncRelevance" />
</div>
</template>
@ -220,18 +201,11 @@ export default {
// todo
if (this.language !== 'beanshell' && this.language !== 'groovy') {
if (
obj.title ===
this.$t('api_test.request.processor.code_add_report_length') ||
obj.title ===
this.$t('api_test.request.processor.code_hide_report_length')
obj.title === this.$t('api_test.request.processor.code_add_report_length') ||
obj.title === this.$t('api_test.request.processor.code_hide_report_length')
) {
this.$warning(
this.$t('commons.no_corresponding') +
' ' +
this.language +
' ' +
this.$t('commons.code_template') +
''
this.$t('commons.no_corresponding') + ' ' + this.language + ' ' + this.$t('commons.code_template') + ''
);
return;
}

View File

@ -50,8 +50,7 @@ function groovyCode(requestObj) {
let path = getMockPath(domain, port, host);
requestPath = path + replaceRestParams(requestPath, requestRest);
if (protocol && host && requestPath) {
requestUrl =
protocol + '://' + domain + (port ? ':' + port : '') + requestPath;
requestUrl = protocol + '://' + domain + (port ? ':' + port : '') + requestPath;
}
let body = JSON.stringify(requestBody);
if (requestMethod === 'POST' && bodyType === 'kvs') {
@ -170,23 +169,9 @@ function getGroovyHeaders(requestHeaders) {
}
function _pythonCodeTemplate(obj) {
let {
requestBody,
requestBodyKvs,
bodyType,
headers,
requestPath,
requestMethod,
connType,
domain,
port,
} = obj;
let { requestBody, requestBodyKvs, bodyType, headers, requestPath, requestMethod, connType, domain, port } = obj;
let reqBody = obj.requestBody;
if (
requestMethod.toLowerCase() === 'post' &&
obj.bodyType === 'kvs' &&
obj.requestBodyKvs
) {
if (requestMethod.toLowerCase() === 'post' && obj.bodyType === 'kvs' && obj.requestBodyKvs) {
reqBody = 'urllib.urlencode({';
// 设置post参数
for (let [k, v] of requestBodyKvs) {
@ -194,8 +179,7 @@ function _pythonCodeTemplate(obj) {
}
reqBody += `})`;
if (headers === '{}') {
headers =
"{'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'}";
headers = "{'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'}";
}
}
@ -275,9 +259,7 @@ function _beanshellTemplate(obj) {
.setPath("${requestPath}")
`;
// http 请求类型
let method = requestMethod
.toLowerCase()
.replace(/^\S/, (s) => s.toUpperCase());
let method = requestMethod.toLowerCase().replace(/^\S/, (s) => s.toUpperCase());
let httpMethodCode = `Http${method} request = new Http${method}(uri);`;
// 设置参数
for (let [k, v] of requestArguments) {
@ -322,10 +304,7 @@ function _beanshellTemplate(obj) {
let postMethodCode = '';
if (requestMethod === 'POST') {
if (bodyType === 'kvs') {
postMethodCode =
postKvsParam +
'\r\n' +
`request.setEntity(new UrlEncodedFormEntity(nameValueList, "UTF-8"));`;
postMethodCode = postKvsParam + '\r\n' + `request.setEntity(new UrlEncodedFormEntity(nameValueList, "UTF-8"));`;
} else {
postMethodCode = `request.setEntity(new StringEntity(StringEscapeUtils.unescapeJava(payload)));`;
}

View File

@ -25,21 +25,15 @@ export const SCRIPT_MENU = [
value: 'vars.put("variable_name", "variable_value")',
},
{
title: i18n.t(
'api_test.request.processor.code_template_get_response_header'
),
title: i18n.t('api_test.request.processor.code_template_get_response_header'),
value: 'prev.getResponseHeaders()',
},
{
title: i18n.t(
'api_test.request.processor.code_template_get_response_code'
),
title: i18n.t('api_test.request.processor.code_template_get_response_code'),
value: 'prev.getResponseCode()',
},
{
title: i18n.t(
'api_test.request.processor.code_template_get_response_result'
),
title: i18n.t('api_test.request.processor.code_template_get_response_result'),
value: 'prev.getResponseDataAsString()',
},
],
@ -48,12 +42,8 @@ export const SCRIPT_MENU = [
title: i18n.t('project.code_segment.project_env'),
children: [
{
title: i18n.t(
'api_test.request.processor.param_environment_set_global_variable'
),
value:
'vars.put(${__metersphere_env_id}+"key","value");\n' +
'vars.put("key","value")',
title: i18n.t('api_test.request.processor.param_environment_set_global_variable'),
value: 'vars.put(${__metersphere_env_id}+"key","value");\n' + 'vars.put("key","value")',
},
],
},
@ -71,8 +61,7 @@ export const SCRIPT_MENU = [
children: [
{
title: i18n.t('project.code_segment.stop_test'),
value:
'ctx.getEngine().stopThreadNow(ctx.getThread().getThreadName());',
value: 'ctx.getEngine().stopThreadNow(ctx.getThread().getThreadName());',
},
],
},

View File

@ -14,15 +14,9 @@
:show-btn="showBtn"
:show-version="showVersion"
:title="displayTitle"
:if-from-variable-advance="ifFromVariableAdvance"
>
<template
v-slot:afterTitle
v-if="request.refType === 'API' || request.refType === 'CASE'"
>
<span v-if="request.num" @click="clickResource(request)">{{
' ID: ' + request.num + ''
}}</span>
:if-from-variable-advance="ifFromVariableAdvance">
<template v-slot:afterTitle v-if="request.refType === 'API' || request.refType === 'CASE'">
<span v-if="request.num" @click="clickResource(request)">{{ ' ID: ' + request.num + '' }}</span>
<span v-else>
<el-tooltip
class="ms-num"
@ -32,8 +26,7 @@
? $t('api_test.automation.scenario.api_none')
: $t('api_test.automation.scenario.case_none')
"
placement="top"
>
placement="top">
<i class="el-icon-warning" />
</el-tooltip>
</span>
@ -43,26 +36,14 @@
</template>
<template v-slot:behindHeaderLeft>
<el-tag
size="small"
class="ms-tag"
v-if="request.referenced === 'Deleted'"
type="danger"
>
<el-tag size="small" class="ms-tag" v-if="request.referenced === 'Deleted'" type="danger">
{{ $t('api_test.automation.reference_deleted') }}
</el-tag>
<el-tag
size="small"
class="ms-tag"
v-if="request.referenced === 'Copy'"
>{{ $t('commons.copy') }}</el-tag
>
<el-tag size="small" class="ms-tag" v-if="request.referenced === 'Copy'">{{ $t('commons.copy') }}</el-tag>
<el-tag size="small" class="ms-tag" v-if="request.referenced === 'REF'"
>{{ $t('api_test.scenario.reference') }}
</el-tag>
<span class="ms-tag ms-step-name-api">{{
getProjectName(request.projectId)
}}</span>
<span class="ms-tag ms-step-name-api">{{ getProjectName(request.projectId) }}</span>
</template>
<template v-slot:debugStepCode>
<span v-if="request.testing" class="ms-test-running">
@ -80,59 +61,40 @@
request.requestResult[0] &&
request.requestResult[0].responseResult &&
request.requestResult[0].status === 'FAKE_ERROR'
"
>
">
FakeError
</span>
<span
class="ms-step-debug-code"
@click="active"
:class="
request.requestResult[0].success && reqSuccess
? 'ms-req-success'
: 'ms-req-error'
"
:class="request.requestResult[0].success && reqSuccess ? 'ms-req-success' : 'ms-req-error'"
v-else-if="
!loading &&
!request.testing &&
request.debug &&
request.requestResult[0] &&
request.requestResult[0].responseResult
"
>
{{
request.requestResult[0].success && reqSuccess ? 'Success' : 'Error'
}}
">
{{ request.requestResult[0].success && reqSuccess ? 'Success' : 'Error' }}
</span>
</template>
<template v-slot:button v-if="!ifFromVariableAdvance">
<el-tooltip
:content="$t('api_test.run')"
placement="top"
v-if="!loading"
>
<el-tooltip :content="$t('api_test.run')" placement="top" v-if="!loading">
<el-button
:disabled="!request.enable"
@click="run"
icon="el-icon-video-play"
class="ms-btn"
size="mini"
circle
/>
circle />
</el-tooltip>
<el-tooltip
:content="$t('report.stop_btn')"
placement="top"
:enterable="false"
v-else
>
<el-tooltip :content="$t('report.stop_btn')" placement="top" :enterable="false" v-else>
<el-button
@click.once="stop"
size="mini"
style="color: white; padding: 0 0.1px; width: 24px; height: 24px"
class="stop-btn"
circle
>
circle>
<div style="transform: scale(0.66)">
<span style="margin-left: -4.5px; font-weight: bold">STOP</span>
</div>
@ -143,17 +105,10 @@
<template v-slot:request>
<legend style="width: 100%; display: table-column">
<div v-if="!ifFromVariableAdvance">
<customize-req-info
:is-customize-req="isCustomizeReq"
:request="request"
@setDomain="setDomain"
/>
<customize-req-info :is-customize-req="isCustomizeReq" :request="request" @setDomain="setDomain" />
<p class="tip">{{ $t('api_test.definition.request.req_param') }}</p>
<ms-api-request-form
v-if="
request.protocol === 'HTTP' ||
request.type === 'HTTPSamplerProxy'
"
v-if="request.protocol === 'HTTP' || request.type === 'HTTPSamplerProxy'"
:scenario-definition="scenarioDefinition"
@editScenarioAdvance="editScenarioAdvance"
:isShowEnable="true"
@ -162,8 +117,7 @@
:scenarioId="currentScenario.id"
:headers="request.headers"
:is-read-only="isCompReadOnly"
:request="request"
/>
:request="request" />
<mx-esb-definition
v-if="request.esbDataStruct != null"
v-xpack
@ -172,44 +126,31 @@
:showScript="true"
:show-pre-script="true"
:is-read-only="isCompReadOnly"
ref="esbDefinition"
/>
ref="esbDefinition" />
<ms-tcp-format-parameters
v-if="
(request.protocol === 'TCP' || request.type === 'TCPSampler') &&
request.esbDataStruct == null
"
v-if="(request.protocol === 'TCP' || request.type === 'TCPSampler') && request.esbDataStruct == null"
:is-read-only="isCompReadOnly"
:response="response"
:show-pre-script="true"
:scenarioId="currentScenario.id"
:show-script="true"
:request="request"
/>
:request="request" />
<ms-sql-basis-parameters
v-if="
request.protocol === 'SQL' || request.type === 'JDBCSampler'
"
v-if="request.protocol === 'SQL' || request.type === 'JDBCSampler'"
:request="request"
:response="response"
:scenarioId="currentScenario.id"
:is-read-only="isCompReadOnly"
:showScript="true"
/>
:showScript="true" />
<ms-dubbo-basis-parameters
v-if="
request.protocol === 'DUBBO' ||
request.protocol === 'dubbo://' ||
request.type === 'DubboSampler'
"
v-if="request.protocol === 'DUBBO' || request.protocol === 'dubbo://' || request.type === 'DubboSampler'"
:request="request"
:scenarioId="currentScenario.id"
:response="response"
:is-read-only="isCompReadOnly"
:showScript="true"
/>
:showScript="true" />
</div>
</legend>
</template>
@ -225,35 +166,27 @@
:show-options-button="false"
:show-header="true"
:result="request.requestResult"
v-xpack
/>
v-xpack />
</div>
<div v-else>
<el-tabs
v-model="request.activeName"
closable
class="ms-tabs"
v-if="request.requestResult && request.requestResult.length > 1"
>
v-if="request.requestResult && request.requestResult.length > 1">
<el-tab-pane
v-for="(item, i) in request.requestResult"
:label="'循环' + (i + 1)"
:key="i"
style="margin-bottom: 5px"
>
<api-response-component
:currentProtocol="request.protocol"
:apiActive="true"
:result="item"
/>
style="margin-bottom: 5px">
<api-response-component :currentProtocol="request.protocol" :apiActive="true" :result="item" />
</el-tab-pane>
</el-tabs>
<api-response-component
:currentProtocol="request.protocol"
:apiActive="true"
:result="request.requestResult[0]"
v-else
/>
v-else />
</div>
</div>
</template>
@ -265,17 +198,13 @@
:env-map="environmentMap"
@runRefresh="runRefresh"
@errorRefresh="errorRefresh"
ref="runTest"
/>
ref="runTest" />
</div>
</template>
<script>
import { getApiCaseById, getCaseById } from '@/api/api-test-case';
import {
getCurrentProjectID,
getCurrentWorkspaceId,
} from 'metersphere-frontend/src/utils/token';
import { getCurrentProjectID, getCurrentWorkspaceId } from 'metersphere-frontend/src/utils/token';
import { getUUID } from 'metersphere-frontend/src/utils';
import { getUrl } from '@/business/automation/scenario/component/urlhelper';
import { getCurrentByResourceId } from '@/api/user';
@ -319,25 +248,17 @@ export default {
},
},
components: {
CustomizeReqInfo: () =>
import('@/business/automation/scenario/common/CustomizeReqInfo'),
CustomizeReqInfo: () => import('@/business/automation/scenario/common/CustomizeReqInfo'),
ApiBaseComponent: () => import('../common/ApiBaseComponent'),
ApiResponseComponent: () => import('./ApiResponseComponent'),
MsSqlBasisParameters: () =>
import('../../../definition/components/request/database/BasisParameters'),
MsTcpFormatParameters: () =>
import('../../../definition/components/request/tcp/TcpFormatParameters'),
MsDubboBasisParameters: () =>
import('../../../definition/components/request/dubbo/BasisParameters'),
MsApiRequestForm: () =>
import('../../../definition/components/request/http/ApiHttpRequestForm'),
MsRequestResultTail: () =>
import('../../../definition/components/response/RequestResultTail'),
MsSqlBasisParameters: () => import('../../../definition/components/request/database/BasisParameters'),
MsTcpFormatParameters: () => import('../../../definition/components/request/tcp/TcpFormatParameters'),
MsDubboBasisParameters: () => import('../../../definition/components/request/dubbo/BasisParameters'),
MsApiRequestForm: () => import('../../../definition/components/request/http/ApiHttpRequestForm'),
MsRequestResultTail: () => import('../../../definition/components/response/RequestResultTail'),
MsRun: () => import('../../../definition/components/Run'),
MxEsbDefinition: () =>
import('@/business/definition/components/esb/MxEsbDefinition'),
MxEsbDefinitionResponse: () =>
import('@/business/definition/components/esb/MxEsbDefinitionResponse'),
MxEsbDefinition: () => import('@/business/definition/components/esb/MxEsbDefinition'),
MxEsbDefinitionResponse: () => import('@/business/definition/components/esb/MxEsbDefinitionResponse'),
},
data() {
return {
@ -362,8 +283,7 @@ export default {
this.request.requestResult = [{ responseResult: {} }];
} else if (
this.request.requestResult &&
Object.prototype.toString.call(this.request.requestResult) !==
'[object Array]'
Object.prototype.toString.call(this.request.requestResult) !== '[object Array]'
) {
let obj = JSON.parse(JSON.stringify(this.request.requestResult));
this.request.requestResult = [obj];
@ -454,10 +374,7 @@ export default {
},
isApiImport() {
let verifies = ['Deleted', 'REF', 'Copy'];
return (
this.request.referenced &&
verifies.indexOf(this.request.referenced) !== -1
);
return this.request.referenced && verifies.indexOf(this.request.referenced) !== -1;
},
isExternalImport() {
return this.request.referenced && this.request.referenced === 'TO_IMPORT';
@ -467,10 +384,7 @@ export default {
},
isDeletedOrRef() {
let verifies = ['Deleted', 'REF'];
return (
this.request.referenced &&
verifies.indexOf(this.request.referenced) !== -1
);
return this.request.referenced && verifies.indexOf(this.request.referenced) !== -1;
},
projectId() {
return getCurrentProjectID();
@ -479,18 +393,11 @@ export default {
methods: {
setOwnEnvironment(scenarioDefinition) {
for (let i in scenarioDefinition) {
let typeArray = [
'JDBCPostProcessor',
'JDBCSampler',
'JDBCPreProcessor',
];
let typeArray = ['JDBCPostProcessor', 'JDBCSampler', 'JDBCPreProcessor'];
if (typeArray.indexOf(scenarioDefinition[i].type) !== -1) {
scenarioDefinition[i].currentScenarioId = this.currentScenario.id;
}
if (
scenarioDefinition[i].hashTree &&
scenarioDefinition[i].hashTree.length > 0
) {
if (scenarioDefinition[i].hashTree && scenarioDefinition[i].hashTree.length > 0) {
this.setOwnEnvironment(scenarioDefinition[i].hashTree);
}
}
@ -505,10 +412,7 @@ export default {
}
});
});
} else if (
this.request.requestResult &&
this.request.requestResult.length > 1
) {
} else if (this.request.requestResult && this.request.requestResult.length > 1) {
this.request.requestResult.forEach((item) => {
if (!item.success) {
this.reqSuccess = item.success;
@ -534,10 +438,7 @@ export default {
new URL(url);
this.request.url = url;
} catch (e) {
if (
url &&
(!url.startsWith('http://') || !url.startsWith('https://'))
) {
if (url && (!url.startsWith('http://') || !url.startsWith('https://'))) {
if (!this.isCustomizeReq) {
this.request.path = url;
this.request.url = undefined;
@ -548,11 +449,7 @@ export default {
mergeHashTree(targetHashTree) {
let sourceHashTree = this.request.hashTree;
//
if (
sourceHashTree &&
targetHashTree &&
sourceHashTree.length < targetHashTree.length
) {
if (sourceHashTree && targetHashTree && sourceHashTree.length < targetHashTree.length) {
this.request.hashTree = targetHashTree;
return;
}
@ -593,11 +490,7 @@ export default {
}
}
//
if (
!source.id &&
source.label !== 'SCENARIO-REF-STEP' &&
index < targetHashTree.length
) {
if (!source.id && source.label !== 'SCENARIO-REF-STEP' && index < targetHashTree.length) {
Object.assign(sourceHashTree[index], targetHashTree[index]);
sourceHashTree[index].disabled = true;
sourceHashTree[index].label = '';
@ -607,9 +500,7 @@ export default {
}
//
delIds.forEach((item) => {
const removeIndex = sourceHashTree.findIndex(
(d) => d.id && d.id === item
);
const removeIndex = sourceHashTree.findIndex((d) => d.id && d.id === item);
sourceHashTree.splice(removeIndex, 1);
});
@ -659,13 +550,9 @@ export default {
if (
store.scenarioEnvMap &&
store.scenarioEnvMap instanceof Map &&
store.scenarioEnvMap.has(
this.currentScenario.id + '_' + this.request.projectId
)
store.scenarioEnvMap.has(this.currentScenario.id + '_' + this.request.projectId)
) {
selectEnvId = store.scenarioEnvMap.get(
this.currentScenario.id + '_' + this.request.projectId
);
selectEnvId = store.scenarioEnvMap.get(this.currentScenario.id + '_' + this.request.projectId);
this.environmentMap = this.envMap;
}
if (!selectEnvId) {
@ -690,9 +577,7 @@ export default {
//
let variables = [];
if (this.currentScenario && this.currentScenario.variables) {
variables = JSON.parse(
JSON.stringify(this.currentScenario.variables)
);
variables = JSON.parse(JSON.stringify(this.currentScenario.variables));
}
let debugData = {
id: this.currentScenario.id,
@ -797,10 +682,7 @@ export default {
clickCase(resource) {
let uri = getUrl(resource);
let resourceId = resource.sourceId;
if (
resourceId &&
resourceId.startsWith('"' || resourceId.startsWith('['))
) {
if (resourceId && resourceId.startsWith('"' || resourceId.startsWith('['))) {
resourceId = JSON.parse(resource.sourceId);
}
if (resourceId instanceof Array) {

View File

@ -8,11 +8,7 @@
<el-collapse-transition>
<div v-if="isActive">
<el-divider></el-divider>
<ms-request-result-tail
:currentProtocol="currentProtocol"
:show-metric="false"
:response="response"
/>
<ms-request-result-tail :currentProtocol="currentProtocol" :show-metric="false" :response="response" />
</div>
</el-collapse-transition>
</el-card>

View File

@ -19,59 +19,33 @@
:environmentType="environmentType"
:environmentGroupId="environmentGroupId"
:envMap="envMap"
:title="$t('commons.scenario')"
>
:title="$t('commons.scenario')">
<template v-slot:afterTitle>
<span v-if="isShowNum" @click="clickResource(scenario)">{{
' ID: ' + scenario.num + ''
}}</span>
<span v-if="isShowNum" @click="clickResource(scenario)">{{ ' ID: ' + scenario.num + '' }}</span>
<span v-else>
<el-tooltip
class="ms-num"
effect="dark"
:content="$t('api_test.automation.scenario.num_none')"
placement="top"
>
<el-tooltip class="ms-num" effect="dark" :content="$t('api_test.automation.scenario.num_none')" placement="top">
<i class="el-icon-warning" />
</el-tooltip>
</span>
<span v-xpack v-if="scenario.versionEnable"
>{{ $t('project.version.name') }}: {{ scenario.versionName }}</span
>
<span v-xpack v-if="scenario.versionEnable">{{ $t('project.version.name') }}: {{ scenario.versionName }}</span>
</template>
<template v-slot:behindHeaderLeft>
<el-tag
size="small"
class="ms-tag"
v-if="scenario.referenced === 'Deleted'"
type="danger"
>
<el-tag size="small" class="ms-tag" v-if="scenario.referenced === 'Deleted'" type="danger">
{{ $t('api_test.automation.reference_deleted') }}
</el-tag>
<el-tag
size="small"
class="ms-tag"
v-if="scenario.referenced === 'Copy'"
>{{ $t('commons.copy') }}</el-tag
>
<el-tag size="small" class="ms-tag" v-if="scenario.referenced === 'Copy'">{{ $t('commons.copy') }}</el-tag>
<el-tag size="small" class="ms-tag" v-if="scenario.referenced === 'REF'"
>{{ $t('api_test.scenario.reference') }}
</el-tag>
<span class="ms-tag ms-step-name-api">{{
getProjectName(scenario.projectId)
}}</span>
<span class="ms-tag ms-step-name-api">{{ getProjectName(scenario.projectId) }}</span>
<el-tooltip
v-if="
(!scenario.hashTree || scenario.hashTree.length === 0) &&
scenario.referenced === 'REF'
"
v-if="(!scenario.hashTree || scenario.hashTree.length === 0) && scenario.referenced === 'REF'"
class="ms-num"
effect="dark"
:content="$t('api_test.scenario.base_scenario_step_is_empty')"
placement="top"
style="margin-left: 5px"
>
style="margin-left: 5px">
<i class="el-icon-warning" />
</el-tooltip>
</template>
@ -83,17 +57,12 @@
<span
class="ms-step-debug-code"
:class="node.data.code === 'ERROR' ? 'ms-req-error' : 'ms-req-success'"
v-if="!loading && node.data.debug && !node.data.testing"
>
v-if="!loading && node.data.debug && !node.data.testing">
{{ getCode() }}
</span>
</template>
<template v-slot:button v-if="!ifFromVariableAdvance">
<el-tooltip
:content="$t('api_test.run')"
placement="top"
v-if="!scenario.run"
>
<el-tooltip :content="$t('api_test.run')" placement="top" v-if="!scenario.run">
<el-button
:disabled="!scenario.enable"
@click="run"
@ -101,23 +70,16 @@
style="padding: 5px"
class="ms-btn"
size="mini"
circle
/>
circle />
</el-tooltip>
<el-tooltip
:content="$t('report.stop_btn')"
placement="top"
:enterable="false"
v-else
>
<el-tooltip :content="$t('report.stop_btn')" placement="top" :enterable="false" v-else>
<el-button
:disabled="!scenario.enable"
@click.once="stop"
size="mini"
style="color: white; padding: 0 0.1px; width: 24px; height: 24px"
class="stop-btn"
circle
>
circle>
<div style="transform: scale(0.66)">
<span style="margin-left: -4.5px; font-weight: bold">STOP</span>
</div>
@ -133,18 +95,11 @@ import MsTcpBasisParameters from '../../../definition/components/request/tcp/Tcp
import MsDubboBasisParameters from '../../../definition/components/request/dubbo/BasisParameters';
import MsApiRequestForm from '../../../definition/components/request/http/ApiHttpRequestForm';
import ApiBaseComponent from '../common/ApiBaseComponent';
import {
getCurrentProjectID,
getCurrentWorkspaceId,
} from 'metersphere-frontend/src/utils/token';
import { getCurrentProjectID, getCurrentWorkspaceId } from 'metersphere-frontend/src/utils/token';
import { getUUID, strMapToObj } from 'metersphere-frontend/src/utils';
import { STEP } from '@/business/automation/scenario/Setting';
import { getOwnerProjectIds, getProject } from '@/api/project';
import {
checkScenarioEnv,
getScenarioById,
setScenarioDomain,
} from '@/api/scenario';
import { checkScenarioEnv, getScenarioById, setScenarioDomain } from '@/api/scenario';
export default {
name: 'ApiScenarioComponent',
@ -186,23 +141,14 @@ export default {
this.reload();
},
'node.data.isBatchProcess'() {
if (
this.node.data &&
this.node.data.isBatchProcess &&
this.node.data.referenced === 'REF'
) {
if (this.node.data && this.node.data.isBatchProcess && this.node.data.referenced === 'REF') {
this.node.expanded = false;
}
},
},
created() {
this.isShowNum = this.scenario.num ? true : false;
if (
this.scenario.id &&
this.scenario.referenced === 'REF' &&
!this.scenario.loaded &&
this.scenario.hashTree
) {
if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded && this.scenario.hashTree) {
this.scenario.root = this.node.parent.parent ? false : true;
this.scenario.disabled = true;
this.recursive(this.scenario.hashTree, this.scenario.projectId, true);
@ -225,10 +171,7 @@ export default {
},
computed: {
isDeletedOrRef() {
return (
(this.scenario.referenced && this.scenario.referenced === 'Deleted') ||
this.scenario.referenced === 'REF'
);
return (this.scenario.referenced && this.scenario.referenced === 'Deleted') || this.scenario.referenced === 'REF';
},
},
methods: {
@ -239,9 +182,7 @@ export default {
}
this.scenario.run = true;
let runScenario = JSON.parse(JSON.stringify(this.scenario));
let variables = JSON.parse(
JSON.stringify(this.currentScenario.variables)
);
let variables = JSON.parse(JSON.stringify(this.currentScenario.variables));
//
if (runScenario && runScenario.variableEnable && runScenario.variables) {
@ -297,9 +238,7 @@ export default {
getCode() {
if (this.node && this.node.data.code && this.node.data.debug) {
let status = this.node.data.code;
return (
status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1)
);
return status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1);
}
return '';
},
@ -308,19 +247,14 @@ export default {
},
active() {
if (this.node) {
if (
this.node.data &&
this.node.data.isBatchProcess &&
this.node.data.referenced === 'REF'
) {
if (this.node.data && this.node.data.isBatchProcess && this.node.data.referenced === 'REF') {
this.node.expanded = false;
} else {
this.node.expanded = !this.node.expanded;
}
}
if (this.scenario && this.scenario.hashTree && this.node.expanded) {
this.scenario.disabled =
this.scenario.id && this.scenario.referenced === 'REF';
this.scenario.disabled = this.scenario.id && this.scenario.referenced === 'REF';
this.recursive(
this.scenario.hashTree,
this.scenario.projectId,
@ -346,11 +280,7 @@ export default {
arr[i].disabled = disabled;
arr[i].projectId = this.calcProjectId(arr[i].projectId, id);
//
let typeArray = [
'JDBCPostProcessor',
'JDBCSampler',
'JDBCPreProcessor',
];
let typeArray = ['JDBCPostProcessor', 'JDBCSampler', 'JDBCPreProcessor'];
if (typeArray.indexOf(arr[i].type) !== -1) {
arr[i].refEevMap = new Map();
arr[i].environmentEnable = this.scenario.environmentEnable;

View File

@ -37,8 +37,7 @@
@openScenario="openScenario"
@setDomain="setDomain"
@savePreParams="savePreParams"
@editScenarioAdvance="editScenarioAdvance"
/>
@editScenarioAdvance="editScenarioAdvance" />
</div>
</template>
@ -64,12 +63,9 @@ export default {
JmeterElementComponent,
MsConstantTimer: () => import('./ConstantTimer'),
MsJsr233Processor: () => import('./Jsr233Processor'),
MsScenarioAssertions: () =>
import('../../../definition/components/assertion/ScenarioAssertions'),
MsApiExtract: () =>
import('../../../definition/components/extract/ApiExtract'),
MsJdbcProcessor: () =>
import('@/business/automation/scenario/component/JDBCProcessor'),
MsScenarioAssertions: () => import('../../../definition/components/assertion/ScenarioAssertions'),
MsApiExtract: () => import('../../../definition/components/extract/ApiExtract'),
MsJdbcProcessor: () => import('@/business/automation/scenario/component/JDBCProcessor'),
},
props: {
type: String,
@ -209,12 +205,7 @@ export default {
this.backgroundColor = '#F2ECF3';
return 'PluginComponent';
} else if (type === ELEMENT_TYPE.Assertions) {
if (
this.node &&
this.node.parent &&
this.node.parent.data &&
this.node.parent.data.referenced === 'REF'
) {
if (this.node && this.node.parent && this.node.parent.data && this.node.parent.data.referenced === 'REF') {
this.apiId = this.node.parent.data.id;
this.scenario.document.nodeType = 'scenario';
} else {

View File

@ -9,8 +9,7 @@
:inner-step="innerStep"
color="#67C23A"
background-color="#F2F9EE"
:title="$t('api_test.automation.wait_controller')"
>
:title="$t('api_test.automation.wait_controller')">
<template v-slot:headerLeft>
<el-input-number
class="time-input"
@ -19,8 +18,7 @@
:min="0"
:step="1000"
ref="nameInput"
:disabled="timer.disabled"
/>
:disabled="timer.disabled" />
ms
</template>
</api-base-component>

View File

@ -11,30 +11,22 @@
color="#E6A23C"
background-color="#FCF6EE"
:if-from-variable-advance="ifFromVariableAdvance"
:title="$t('api_test.automation.if_controller')"
>
:title="$t('api_test.automation.if_controller')">
<template v-slot:headerLeft>
<el-input
draggable
size="mini"
v-model="controller.variable"
style="width: 12%"
:placeholder="$t('api_test.request.condition_variable')"
/>
:placeholder="$t('api_test.request.condition_variable')" />
<el-select
v-model="controller.operator"
:placeholder="$t('commons.please_select')"
size="mini"
@change="change"
class="ms-select"
>
<el-option
v-for="o in operators"
:key="o.value"
:label="$t(o.label)"
:value="o.value"
/>
class="ms-select">
<el-option v-for="o in operators" :key="o.value" :label="$t(o.label)" :value="o.value" />
</el-select>
<el-input
@ -43,8 +35,7 @@
v-model="controller.value"
:placeholder="$t('api_test.value')"
v-if="!hasEmptyOperator"
class="ms-btn"
/>
class="ms-btn" />
<el-input
draggable
@ -52,8 +43,7 @@
v-model="controller.remark"
:placeholder="$t('commons.remark')"
v-if="!hasEmptyOperator && !isMax"
class="ms-btn"
/>
class="ms-btn" />
</template>
<template v-slot:debugStepCode>
@ -64,10 +54,7 @@
<span
class="ms-step-debug-code"
:class="node.data.code === 'ERROR' ? 'ms-req-error' : 'ms-req-success'"
v-if="
!loading && !node.data.testing && node.data.debug && node.data.code
"
>
v-if="!loading && !node.data.testing && node.data.debug && node.data.code">
{{ getCode() }}
</span>
</template>
@ -160,9 +147,7 @@ export default {
getCode() {
if (this.node && this.node.data.code && this.node.data.debug) {
let status = this.node.data.code;
return (
status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1)
);
return status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1);
}
return '';
},
@ -180,10 +165,7 @@ export default {
},
computed: {
hasEmptyOperator() {
return (
!!this.controller.operator &&
this.controller.operator.indexOf('empty') > 0
);
return !!this.controller.operator && this.controller.operator.indexOf('empty') > 0;
},
},
};

View File

@ -11,14 +11,9 @@
:show-version="showVersion"
:background-color="backgroundColor"
:title="title"
v-loading="loading"
>
v-loading="loading">
<template v-slot:request>
<jdbc-processor-content
:showScript="false"
:scenarioId="scenarioId"
:request="request"
/>
<jdbc-processor-content :showScript="false" :scenarioId="scenarioId" :request="request" />
</template>
</api-base-component>
</template>

View File

@ -10,15 +10,9 @@
:show-btn="showBtn"
:show-version="showVersion"
:background-color="defBackgroundColor"
:title="request.elementType"
>
:title="request.elementType">
<div style="height: 300px; width: 100%">
<ms-code-edit
mode="xml"
:data.sync="request.jmeterElement"
theme="eclipse"
ref="codeEdit"
/>
<ms-code-edit mode="xml" :data.sync="request.jmeterElement" theme="eclipse" ref="codeEdit" />
</div>
<template v-slot:debugStepCode>
@ -29,8 +23,7 @@
<span
class="ms-step-debug-code"
:class="node.data.code === 'ERROR' ? 'ms-req-error' : 'ms-req-success'"
v-if="!loading && !node.data.testing && node.data.debug"
>
v-if="!loading && !node.data.testing && node.data.debug">
{{ getCode() }}
</span>
</template>
@ -103,9 +96,7 @@ export default {
getCode() {
if (this.node && this.node.data.code && this.node.data.debug) {
let status = this.node.data.code;
return (
status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1)
);
return status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1);
}
return '';
},

View File

@ -12,13 +12,9 @@
:background-color="backgroundColor"
:if-from-variable-advance="ifFromVariableAdvance"
:title="title"
v-loading="loading"
>
v-loading="loading">
<!--自定义脚本-->
<legend
style="width: 100%; display: table-column"
v-if="request && this.request.type === 'JSR223Processor'"
>
<legend style="width: 100%; display: table-column" v-if="request && this.request.type === 'JSR223Processor'">
<p class="ms-tip">{{ $t('api_test.definition.request.req_param') }}</p>
<el-tabs v-model="activeName" class="request-tabs" @tab-click="tabClick">
<!-- 请求头-->
@ -28,26 +24,13 @@
:is-pre-processor="isPreProcessor"
:node="node"
:protocol="protocol"
:is-read-only="this.jsr223Processor.disabled"
/>
:is-read-only="this.jsr223Processor.disabled" />
</el-tab-pane>
<!-- 脚本步骤/断言步骤 -->
<el-tab-pane
:label="$t('api_test.definition.request.pre_operation')"
name="preOperate"
>
<span
class="item-tabs"
effect="dark"
placement="top-start"
slot="label"
:key="request.preSize"
>
<el-tab-pane :label="$t('api_test.definition.request.pre_operation')" name="preOperate">
<span class="item-tabs" effect="dark" placement="top-start" slot="label" :key="request.preSize">
{{ $t('api_test.definition.request.pre_operation') }}
<div
class="el-step__icon is-text ms-api-col ms-header"
v-if="request.preSize > 0"
>
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.preSize > 0">
<div class="el-step__icon-inner">{{ request.preSize }}</div>
</div>
</span>
@ -57,24 +40,12 @@
:response="response"
:tab-type="'pre'"
ref="preStep"
v-if="activeName === 'preOperate'"
/>
v-if="activeName === 'preOperate'" />
</el-tab-pane>
<el-tab-pane
:label="$t('api_test.definition.request.post_operation')"
name="postOperate"
>
<span
class="item-tabs"
effect="dark"
placement="top-start"
slot="label"
>
<el-tab-pane :label="$t('api_test.definition.request.post_operation')" name="postOperate">
<span class="item-tabs" effect="dark" placement="top-start" slot="label">
{{ $t('api_test.definition.request.post_operation') }}
<div
class="el-step__icon is-text ms-api-col ms-header"
v-if="request.postSize > 0"
>
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.postSize > 0">
<div class="el-step__icon-inner" :key="request.postSize">
{{ request.postSize }}
</div>
@ -86,24 +57,12 @@
:response="response"
:tab-type="'post'"
ref="postStep"
v-if="activeName === 'postOperate'"
/>
v-if="activeName === 'postOperate'" />
</el-tab-pane>
<el-tab-pane
:label="$t('api_test.definition.request.assertions_rule')"
name="assertionsRule"
>
<span
class="item-tabs"
effect="dark"
placement="top-start"
slot="label"
>
<el-tab-pane :label="$t('api_test.definition.request.assertions_rule')" name="assertionsRule">
<span class="item-tabs" effect="dark" placement="top-start" slot="label">
{{ $t('api_test.definition.request.assertions_rule') }}
<div
class="el-step__icon is-text ms-api-col ms-header"
v-if="request.ruleSize > 0"
>
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.ruleSize > 0">
<div class="el-step__icon-inner" :key="request.ruleSize">
{{ request.ruleSize }}
</div>
@ -115,8 +74,7 @@
:response="response"
:tab-type="'assertionsRule'"
ref="assertionsRule"
v-if="activeName === 'assertionsRule'"
/>
v-if="activeName === 'assertionsRule'" />
</el-tab-pane>
</el-tabs>
</legend>
@ -128,8 +86,7 @@
:is-pre-processor="isPreProcessor"
:node="node"
:protocol="protocol"
:is-read-only="this.jsr223Processor.disabled"
/>
:is-read-only="this.jsr223Processor.disabled" />
</legend>
<template v-slot:debugStepCode>
<span v-if="jsr223Processor.testing" class="ms-test-running">
@ -138,24 +95,15 @@
</span>
<span
class="ms-step-debug-code"
:class="
jsr223Processor.requestResult[0].success && reqSuccess
? 'ms-req-success'
: 'ms-req-error'
"
:class="jsr223Processor.requestResult[0].success && reqSuccess ? 'ms-req-success' : 'ms-req-error'"
v-if="
!loading &&
!jsr223Processor.testing &&
jsr223Processor.debug &&
jsr223Processor.requestResult[0] &&
jsr223Processor.requestResult[0].responseResult
"
>
{{
jsr223Processor.requestResult[0].success && reqSuccess
? 'Success'
: 'Error'
}}
">
{{ jsr223Processor.requestResult[0].success && reqSuccess ? 'Success' : 'Error' }}
</span>
</template>
@ -163,41 +111,26 @@
<template v-slot:result>
<div
v-loading="loading"
v-if="
jsr223Processor &&
jsr223Processor.requestResult &&
jsr223Processor.requestResult.length > 0
"
>
v-if="jsr223Processor && jsr223Processor.requestResult && jsr223Processor.requestResult.length > 0">
<p class="tip">{{ $t('api_test.definition.request.res_param') }}</p>
<el-tabs
v-model="jsr223Processor.activeName"
closable
class="ms-tabs"
v-if="
jsr223Processor.requestResult &&
jsr223Processor.requestResult.length > 1
"
>
v-if="jsr223Processor.requestResult && jsr223Processor.requestResult.length > 1">
<el-tab-pane
v-for="(item, i) in jsr223Processor.requestResult"
:label="'循环' + (i + 1)"
:key="i"
style="margin-bottom: 5px"
>
<api-response-component
:currentProtocol="jsr223Processor.protocol"
:apiActive="true"
:result="item"
/>
style="margin-bottom: 5px">
<api-response-component :currentProtocol="jsr223Processor.protocol" :apiActive="true" :result="item" />
</el-tab-pane>
</el-tabs>
<api-response-component
:currentProtocol="'HTTP'"
:apiActive="true"
:result="jsr223Processor.requestResult[0]"
v-else
/>
v-else />
</div>
</template>
</api-base-component>
@ -210,10 +143,7 @@ import MsDropdown from '@/business/commons/MsDropdown';
import ApiBaseComponent from '../common/ApiBaseComponent';
import Jsr233ProcessorContent from '../common/Jsr233ProcessorContent';
import ApiResponseComponent from './ApiResponseComponent';
import {
stepCompute,
hisDataProcessing,
} from '@/business/definition/api-definition';
import { stepCompute, hisDataProcessing } from '@/business/definition/api-definition';
export default {
name: 'MsJsr233Processor',
@ -267,11 +197,7 @@ export default {
},
},
created() {
if (
this.request &&
this.request.type === 'JSR223Processor' &&
this.request.hashTree
) {
if (this.request && this.request.type === 'JSR223Processor' && this.request.hashTree) {
this.initStepSize(this.request.hashTree);
this.historicalDataProcessing(this.request.hashTree);
}
@ -324,11 +250,7 @@ export default {
}
},
forStatus() {
if (
this.jsr223Processor &&
this.jsr223Processor.result &&
this.jsr223Processor.result.length > 0
) {
if (this.jsr223Processor && this.jsr223Processor.result && this.jsr223Processor.result.length > 0) {
this.jsr223Processor.result.forEach((item) => {
item.requestResult.forEach((req) => {
if (!req.success) {
@ -350,10 +272,7 @@ export default {
}
});
}
if (
this.jsr223Processor.requestResult &&
this.jsr223Processor.requestResult.length > 0
) {
if (this.jsr223Processor.requestResult && this.jsr223Processor.requestResult.length > 0) {
this.response = this.jsr223Processor.requestResult[0];
}
},

View File

@ -9,8 +9,7 @@
:run-data="debugData"
@errorRefresh="errorRefresh"
@runRefresh="runRefresh"
ref="runTest"
/>
ref="runTest" />
<api-base-component
:if-from-variable-advance="ifFromVariableAdvance"
:data="controller"
@ -23,22 +22,19 @@
@active="active(controller)"
@remove="remove"
color="#02A7F0"
background-color="#F4F4F5"
>
background-color="#F4F4F5">
<template v-slot:headerLeft>
<i
class="icon el-icon-arrow-right"
:class="{ 'is-active': controller.active }"
style="margin-right: 10px"
v-if="!isMax"
/>
v-if="!isMax" />
<el-radio
:disabled="controller.disabled"
@change="changeRadio"
class="ms-radio ms-radio-margin"
v-model="controller.loopType"
label="LOOP_COUNT"
>
label="LOOP_COUNT">
{{ $t('loop.loops_title') }}
</el-radio>
<el-radio
@ -46,8 +42,7 @@
@change="changeRadio"
class="ms-radio ms-radio-margin"
v-model="controller.loopType"
label="FOREACH"
>
label="FOREACH">
{{ $t('loop.foreach') }}
</el-radio>
<el-radio
@ -55,21 +50,15 @@
@change="changeRadio"
class="ms-radio ms-radio-margin"
v-model="controller.loopType"
label="WHILE"
>
label="WHILE">
{{ $t('loop.while') }}
</el-radio>
</template>
<template v-slot:message>
<span
v-if="
requestResult &&
requestResult.scenarios &&
requestResult.scenarios.length > 0
"
style="color: #8c939d; margin-right: 10px"
/>
v-if="requestResult && requestResult.scenarios && requestResult.scenarios.length > 0"
style="color: #8c939d; margin-right: 10px" />
</template>
<template v-slot:button>
@ -80,22 +69,13 @@
icon="el-icon-video-play"
class="ms-conn"
size="mini"
circle
/>
circle />
</template>
<div
v-if="controller.loopType === 'LOOP_COUNT'"
draggable
v-loading="loading"
>
<div v-if="controller.loopType === 'LOOP_COUNT'" draggable v-loading="loading">
<el-row>
<el-col :span="8">
<span class="ms-span ms-radio">{{ $t('loop.loops') }}</span>
<el-input
size="small"
v-model="controller.countController.loops"
style="width: 200px"
/>
<el-input size="small" v-model="controller.countController.loops" style="width: 200px" />
<span class="ms-span ms-radio"></span>
</el-col>
<el-col :span="8">
@ -107,41 +87,30 @@
:max="1000 * 10000000"
:min="0"
:step="1000"
size="small"
/>
size="small" />
<span class="ms-span ms-radio">ms</span>
</el-col>
<el-col :span="8">
<span class="ms-span ms-radio">{{ $t('loop.proceed') }}</span>
<el-tooltip
class="item"
effect="dark"
:content="$t('api_test.automation.loop_content')"
placement="top"
<el-tooltip class="item" effect="dark" :content="$t('api_test.automation.loop_content')" placement="top"
>>
<el-switch
:disabled="controller.disabled"
v-model="controller.countController.proceed"
@change="switchChange"
/>
@change="switchChange" />
</el-tooltip>
</el-col>
</el-row>
</div>
<div
v-else-if="controller.loopType === 'FOREACH'"
draggable
v-loading="loading"
>
<div v-else-if="controller.loopType === 'FOREACH'" draggable v-loading="loading">
<el-row>
<el-col :span="8">
<el-input
:disabled="controller.disabled"
:placeholder="$t('api_test.automation.loop_return_val')"
v-model="controller.forEachController.returnVal"
size="small"
/>
size="small" />
</el-col>
<el-col :span="1" style="margin-top: 6px">
<span style="margin: 10px 10px 10px">in</span>
@ -151,8 +120,7 @@
:disabled="controller.disabled"
:placeholder="$t('api_test.automation.loop_input_val')"
v-model="controller.forEachController.inputVal"
size="small"
/>
size="small" />
</el-col>
<el-col :span="7">
<span class="ms-span ms-radio">{{ $t('loop.interval') }}</span>
@ -163,8 +131,7 @@
:placeholder="$t('commons.millisecond')"
:max="1000 * 10000000"
:min="0"
:step="1000"
/>
:step="1000" />
<span class="ms-span ms-radio">ms</span>
</el-col>
</el-row>
@ -175,22 +142,15 @@
:disabled="controller.disabled"
size="small"
:placeholder="$t('api_test.request.condition_variable')"
style="width: 20%"
/>
style="width: 20%" />
<el-select
v-model="controller.whileController.operator"
:disabled="controller.disabled"
:placeholder="$t('commons.please_select')"
size="small"
@change="change"
style="width: 10%; margin-left: 10px"
>
<el-option
v-for="o in operators"
:key="o.value"
:label="$t(o.label)"
:value="o.value"
/>
style="width: 10%; margin-left: 10px">
<el-option v-for="o in operators" :key="o.value" :label="$t(o.label)" :value="o.value" />
</el-select>
<el-input
v-model="controller.whileController.value"
@ -198,8 +158,7 @@
size="small"
:placeholder="$t('api_test.value')"
v-if="!hasEmptyOperator"
style="width: 20%; margin-left: 20px"
/>
style="width: 20%; margin-left: 20px" />
<span class="ms-span ms-radio">{{ $t('loop.timeout') }}</span>
<el-input-number
v-model="controller.whileController.timeout"
@ -208,8 +167,7 @@
:placeholder="$t('commons.millisecond')"
:max="1000 * 10000000"
:min="3000"
:step="1000"
/>
:step="1000" />
<span class="ms-span ms-radio">ms</span>
</div>
@ -220,11 +178,8 @@
</span>
<span
class="ms-step-debug-code"
:class="
node.data.code === 'ERROR' ? 'ms-req-error' : 'ms-req-success'
"
v-if="!loading && !node.data.testing && node.data.debug"
>
:class="node.data.code === 'ERROR' ? 'ms-req-error' : 'ms-req-success'"
v-if="!loading && !node.data.testing && node.data.debug">
{{ getCode() }}
</span>
</template>
@ -359,9 +314,7 @@ export default {
clear(hashTree) {
if (hashTree) {
hashTree.forEach((item) => {
if (
this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1
) {
if (this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1) {
item.requestResult = [];
item.result = undefined;
item.code = undefined;
@ -377,8 +330,7 @@ export default {
if (data.error > 0) {
this.node.data.code = 'error';
} else {
this.node.data.code =
this.node.data.code !== 'ERROR' ? 'Success' : 'Error';
this.node.data.code = this.node.data.code !== 'ERROR' ? 'Success' : 'Error';
}
}
this.reload();
@ -386,9 +338,7 @@ export default {
getCode() {
if (this.node && this.node.data.code && this.node.data.debug) {
let status = this.node.data.code;
return (
status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1)
);
return status.toLowerCase()[0].toUpperCase() + status.toLowerCase().substr(1);
}
return '';
},
@ -407,9 +357,7 @@ export default {
) {
let count = 0;
this.controller.hashTree[0].hashTree.forEach((item) => {
if (
this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1
) {
if (this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1) {
count++;
}
if (item.hashTree && item.hashTree.length > 0) {
@ -425,9 +373,7 @@ export default {
},
recursive(arr, count) {
for (let i in arr) {
if (
this.stepFilter.get('AllSamplerProxy').indexOf(arr[i].type) !== -1
) {
if (this.stepFilter.get('AllSamplerProxy').indexOf(arr[i].type) !== -1) {
count++;
}
if (arr[i].hashTree && arr[i].hashTree.length > 0) {
@ -451,13 +397,8 @@ export default {
runDebug() {
this.loading = true;
let currentEnvironmentId;
let resourceId =
this.currentScenario.id + '_' + this.controller.projectId;
if (
store.scenarioEnvMap &&
store.scenarioEnvMap instanceof Map &&
store.scenarioEnvMap.has(resourceId)
) {
let resourceId = this.currentScenario.id + '_' + this.controller.projectId;
if (store.scenarioEnvMap && store.scenarioEnvMap instanceof Map && store.scenarioEnvMap.has(resourceId)) {
currentEnvironmentId = store.scenarioEnvMap.get(resourceId);
}
this.debugData = {
@ -515,10 +456,7 @@ export default {
setResult(hashTree) {
if (hashTree) {
hashTree.forEach((item) => {
if (
this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1 &&
this.requestResult.has(item.id)
) {
if (this.stepFilter.get('AllSamplerProxy').indexOf(item.type) !== -1 && this.requestResult.has(item.id)) {
item.activeName = '0';
item.active = true;
item.requestResult = this.requestResult.get(item.id);
@ -532,10 +470,7 @@ export default {
},
computed: {
hasEmptyOperator() {
return (
!!this.controller.operator &&
this.controller.operator.indexOf('empty') > 0
);
return !!this.controller.operator && this.controller.operator.indexOf('empty') > 0;
},
},
};
@ -548,8 +483,7 @@ export default {
.ms-radio {
color: #606266;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
font-size: 13px;
font-weight: normal;
}

View File

@ -11,16 +11,11 @@
:show-btn="showBtn"
:show-version="showVersion"
:background-color="defBackgroundColor"
:title="pluginName"
>
:title="pluginName">
<template v-slot:request>
<legend style="width: 100%; display: table-column">
<p class="tip">{{ $t('api_test.definition.request.req_param') }}</p>
<el-tabs
v-model="activeName"
class="request-tabs"
@tab-click="tabClick"
>
<el-tabs v-model="activeName" class="request-tabs" @tab-click="tabClick">
<!-- 请求头-->
<el-tab-pane label="插件数据" name="base">
<div class="ms-form">
@ -33,29 +28,16 @@
@prefix-change="change"
@prefix-click="change"
@display-change="changeDisplay"
@prefix-visible-change="visibleChange"
/>
@prefix-visible-change="visibleChange" />
</div>
</div>
</el-tab-pane>
<!-- 脚本步骤/断言步骤 -->
<el-tab-pane
:label="$t('api_test.definition.request.pre_operation')"
name="preOperate"
v-if="showOther"
>
<span
class="item-tabs"
effect="dark"
placement="top-start"
slot="label"
>
<el-tab-pane :label="$t('api_test.definition.request.pre_operation')" name="preOperate" v-if="showOther">
<span class="item-tabs" effect="dark" placement="top-start" slot="label">
{{ $t('api_test.definition.request.pre_operation') }}
<div
class="el-step__icon is-text ms-api-col ms-header"
v-if="request.preSize > 0"
>
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.preSize > 0">
<div class="el-step__icon-inner">{{ request.preSize }}</div>
</div>
</span>
@ -65,25 +47,12 @@
:scenario-id="currentScenario.id"
:response="response"
:tab-type="'pre'"
ref="preStep"
/>
ref="preStep" />
</el-tab-pane>
<el-tab-pane
:label="$t('api_test.definition.request.post_operation')"
name="postOperate"
v-if="showOther"
>
<span
class="item-tabs"
effect="dark"
placement="top-start"
slot="label"
>
<el-tab-pane :label="$t('api_test.definition.request.post_operation')" name="postOperate" v-if="showOther">
<span class="item-tabs" effect="dark" placement="top-start" slot="label">
{{ $t('api_test.definition.request.post_operation') }}
<div
class="el-step__icon is-text ms-api-col ms-header"
v-if="request.postSize > 0"
>
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.postSize > 0">
<div class="el-step__icon-inner">{{ request.postSize }}</div>
</div>
</span>
@ -93,25 +62,15 @@
:scenario-id="currentScenario.id"
:response="response"
:tab-type="'post'"
ref="postStep"
/>
ref="postStep" />
</el-tab-pane>
<el-tab-pane
:label="$t('api_test.definition.request.assertions_rule')"
name="assertionsRule"
v-if="showOther"
>
<span
class="item-tabs"
effect="dark"
placement="top-start"
slot="label"
>
v-if="showOther">
<span class="item-tabs" effect="dark" placement="top-start" slot="label">
{{ $t('api_test.definition.request.assertions_rule') }}
<div
class="el-step__icon is-text ms-api-col ms-header"
v-if="request.ruleSize > 0"
>
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.ruleSize > 0">
<div class="el-step__icon-inner">{{ request.ruleSize }}</div>
</div>
</span>
@ -123,8 +82,7 @@
:response="response"
@reload="reload"
:tab-type="'assertionsRule'"
ref="assertionsRule"
/>
ref="assertionsRule" />
</div>
</el-tab-pane>
</el-tabs>
@ -138,26 +96,14 @@
</span>
<span
class="ms-step-debug-code"
:class="
request.requestResult[0].success ? 'ms-req-success' : 'ms-req-error'
"
v-if="
!loading &&
request.debug &&
request.requestResult[0] &&
request.requestResult[0].responseResult
"
>
:class="request.requestResult[0].success ? 'ms-req-success' : 'ms-req-error'"
v-if="!loading && request.debug && request.requestResult[0] && request.requestResult[0].responseResult">
{{ request.requestResult[0].success ? 'Success' : 'Error' }}
</span>
</template>
<template v-slot:button v-if="allSampler.indexOf(request.type) !== -1">
<el-tooltip
:content="$t('api_test.run')"
placement="top"
v-if="!loading"
>
<el-tooltip :content="$t('api_test.run')" placement="top" v-if="!loading">
<el-button
:disabled="!request.enable"
@click="run"
@ -165,23 +111,16 @@
style="padding: 5px"
class="ms-btn"
size="mini"
circle
/>
circle />
</el-tooltip>
<el-tooltip
:content="$t('report.stop_btn')"
placement="top"
:enterable="false"
v-else
>
<el-tooltip :content="$t('report.stop_btn')" placement="top" :enterable="false" v-else>
<el-button
:disabled="!request.enable"
@click.once="stop"
size="mini"
style="color: white; padding: 0 0.1px; width: 24px; height: 24px"
class="stop-btn"
circle
>
circle>
<div style="transform: scale(0.66)">
<span style="margin-left: -4.5px; font-weight: bold">STOP</span>
</div>
@ -199,13 +138,8 @@
v-for="(item, i) in scenario.requestResults"
:label="'循环' + (i + 1)"
:key="i"
style="margin-bottom: 5px"
>
<api-response-component
:currentProtocol="request.protocol"
:apiActive="true"
:result="item"
/>
style="margin-bottom: 5px">
<api-response-component :currentProtocol="request.protocol" :apiActive="true" :result="item" />
</el-tab-pane>
</el-tabs>
</div>
@ -215,27 +149,20 @@
v-model="request.activeName"
closable
class="ms-tabs"
v-if="request.requestResult && request.requestResult.length > 1"
>
v-if="request.requestResult && request.requestResult.length > 1">
<el-tab-pane
v-for="(item, i) in request.requestResult"
:label="'循环' + (i + 1)"
:key="i"
style="margin-bottom: 5px"
>
<api-response-component
:currentProtocol="request.protocol"
:apiActive="true"
:result="item"
/>
style="margin-bottom: 5px">
<api-response-component :currentProtocol="request.protocol" :apiActive="true" :result="item" />
</el-tab-pane>
</el-tabs>
<api-response-component
:currentProtocol="request.protocol"
:apiActive="true"
:result="request.requestResult[0]"
v-else
/>
v-else />
</div>
</div>
</template>
@ -247,8 +174,7 @@
:env-map="envMap"
@runRefresh="runRefresh"
@errorRefresh="errorRefresh"
ref="runTest"
/>
ref="runTest" />
</div>
</template>
@ -260,10 +186,7 @@ import MsUpload from '../common/MsPluginUpload';
import { PLUGIN_ELEMENTS } from '@/business/automation/scenario/Setting';
import { getUUID } from 'metersphere-frontend/src/utils';
import MsJmxStep from '@/business/definition/components/step/JmxStep';
import {
stepCompute,
hisDataProcessing,
} from '@/business/definition/api-definition';
import { stepCompute, hisDataProcessing } from '@/business/definition/api-definition';
import MsPluginContentAssertions from '@/business/automation/scenario/component/PluginContentAssertions';
import { execStop } from '@/api/scenario';
import { customMethod, getPlugin } from '@/api/plugin';
@ -336,8 +259,7 @@ export default {
computed: {
isApiImport() {
if (
(this.request.referenced != undefined &&
this.request.referenced === 'Deleted') ||
(this.request.referenced != undefined && this.request.referenced === 'Deleted') ||
this.request.referenced == 'REF' ||
this.request.referenced === 'Copy'
) {
@ -358,10 +280,7 @@ export default {
return false;
},
isDeletedOrRef() {
if (
(this.request.referenced && this.request.referenced === 'Deleted') ||
this.request.referenced === 'REF'
) {
if ((this.request.referenced && this.request.referenced === 'Deleted') || this.request.referenced === 'REF') {
return true;
}
return false;
@ -373,9 +292,7 @@ export default {
this.request.requestResult = [];
}
this.data = this.request;
this.pluginName = this.request.stepName
? this.request.stepName
: this.request.type;
this.pluginName = this.request.stepName ? this.request.stepName : this.request.type;
if (this.request.type === 'GenericController') {
this.showOther = false;
}
@ -430,20 +347,12 @@ export default {
blur(d) {},
change(fileName) {},
changeDisplay(fileName) {
if (
fileName === 'number of received messages' &&
this.pluginForm &&
this.pluginForm.hidden instanceof Function
) {
if (fileName === 'number of received messages' && this.pluginForm && this.pluginForm.hidden instanceof Function) {
this.pluginForm.hidden(false, 'conditionTime');
this.pluginForm.hidden(false, 'conditionValue');
this.pluginForm.hidden(true, 'conditionContent');
}
if (
fileName === 'specified elapsed time (ms)' &&
this.pluginForm &&
this.pluginForm.hidden instanceof Function
) {
if (fileName === 'specified elapsed time (ms)' && this.pluginForm && this.pluginForm.hidden instanceof Function) {
this.pluginForm.hidden(false, 'conditionTime');
this.pluginForm.hidden(true, 'conditionValue');
this.pluginForm.hidden(true, 'conditionContent');
@ -468,13 +377,9 @@ export default {
if (
store.scenarioEnvMap &&
store.scenarioEnvMap instanceof Map &&
store.scenarioEnvMap.has(
this.currentScenario.id + '_' + this.request.projectId
)
store.scenarioEnvMap.has(this.currentScenario.id + '_' + this.request.projectId)
) {
currentEnvironmentId = store.scenarioEnvMap.get(
this.currentScenario.id + '_' + this.request.projectId
);
currentEnvironmentId = store.scenarioEnvMap.get(this.currentScenario.id + '_' + this.request.projectId);
}
let debugData = {
id: this.currentScenario.id,
@ -515,10 +420,7 @@ export default {
let result;
while ((result = reg.exec(val)) !== null) {
if (this.pluginForm.getRule(result[1])) {
val = val.replace(
'$' + result[0],
this.pluginForm.getRule(result[1]).value
);
val = val.replace('$' + result[0], this.pluginForm.getRule(result[1]).value);
}
}
return val;
@ -534,9 +436,7 @@ export default {
};
customMethod(req).then((response) => {
if (response.data && this.pluginForm.getRule(d.inject[0]).options) {
this.pluginForm.getRule(d.inject[0]).options = JSON.parse(
response.data
);
this.pluginForm.getRule(d.inject[0]).options = JSON.parse(response.data);
}
});
this.reload();
@ -559,11 +459,7 @@ export default {
}
this.option.submitBtn = { show: false };
this.request.clazzName = plugin.clazzName;
if (
this.request &&
this.pluginForm &&
this.pluginForm.setValue instanceof Function
) {
if (this.request && this.pluginForm && this.pluginForm.setValue instanceof Function) {
this.pluginForm.setValue(this.request);
}
if (this.request.condition) {
@ -588,10 +484,7 @@ export default {
}
});
});
} else if (
this.request.requestResult &&
this.request.requestResult.length > 1
) {
} else if (this.request.requestResult && this.request.requestResult.length > 1) {
this.request.requestResult.forEach((item) => {
if (!item.success) {
this.reqSuccess = item.success;
@ -629,12 +522,7 @@ export default {
},
active() {
this.request.active = !this.request.active;
if (
this.request &&
this.request.active &&
this.pluginForm &&
this.pluginForm.setValue instanceof Function
) {
if (this.request && this.request.active && this.pluginForm && this.pluginForm.setValue instanceof Function) {
this.pluginForm.setValue(this.request);
}
},

View File

@ -8,100 +8,52 @@
v-model="value.contentType"
style="margin-left: 10px; width: 120px; height: 32px"
:placeholder="$t('api_test.request.assertions.select_type')"
size="small"
>
<el-option
:label="$t('api_test.request.assertions.text')"
:value="options.TEXT"
/>
size="small">
<el-option :label="$t('api_test.request.assertions.text')" :value="options.TEXT" />
<el-option :label="'JSONPath'" :value="options.JSON_PATH" />
<el-option :label="'XPath'" :value="options.XPATH2" />
</el-select>
<el-button
type="primary"
size="mini"
@click="add"
style="margin-left: 20px"
>
<el-button type="primary" size="mini" @click="add" style="margin-left: 20px">
{{ $t('api_test.request.assertions.add') }}
</el-button>
</el-col>
<el-col :span="8" :offset="3">
<span>{{ this.$t('api_test.request.sql.timeout') }}</span>
<el-input
size="mini"
style="width: 100px; margin-left: 10px"
v-model="value.timeOut"
></el-input>
<el-input size="mini" style="width: 100px; margin-left: 10px" v-model="value.timeOut"></el-input>
</el-col>
</el-row>
<el-row>
<el-container>
<el-aside
width="73px"
style="overflow: hidden"
v-if="value.list.length > 1"
>
<el-aside width="73px" style="overflow: hidden" v-if="value.list.length > 1">
<div style="height: 100%" id="moreOptionTypeDiv">
<div
class="ms-top-line-box"
:style="{
height: lineDivTopHeight + 'px',
marginTop: lineDivMarginTopHeight + 'px',
}"
></div>
}"></div>
<div>
<el-select
class="ms-http-select"
size="small"
v-model="value.filterType"
style="width: 70px"
>
<el-option
v-for="item in filterTypes"
:key="item.id"
:label="item.label"
:value="item.id"
/>
<el-select class="ms-http-select" size="small" v-model="value.filterType" style="width: 70px">
<el-option v-for="item in filterTypes" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
</div>
<div
class="ms-bottom-line-box"
:style="{ height: lineDivBottomHeight + 'px' }"
></div>
<div class="ms-bottom-line-box" :style="{ height: lineDivBottomHeight + 'px' }"></div>
</div>
</el-aside>
<el-main style="padding: 0px 20px 0px 0px; overflow: hidden">
<div v-for="(data, index) in value.list" :key="index">
<el-col name="itemOptions">
<div
v-if="data.type === options.TEXT"
class="assertion-item-editing"
>
<el-row
:gutter="10"
type="flex"
justify="space-between"
align="middle"
>
<div v-if="data.type === options.TEXT" class="assertion-item-editing">
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
<el-col class="ms-assertion-select">
<el-select
:disabled="true"
style="width: 120px; height: 32px"
v-model="data.type"
:placeholder="
$t('api_test.request.assertions.select_type')
"
size="small"
>
<el-option
:label="$t('api_test.request.assertions.text')"
:value="options.TEXT"
/>
<el-option
:label="'JSONPath'"
:value="options.JSON_PATH"
/>
:placeholder="$t('api_test.request.assertions.select_type')"
size="small">
<el-option :label="$t('api_test.request.assertions.text')" :value="options.TEXT" />
<el-option :label="'JSONPath'" :value="options.JSON_PATH" />
<el-option :label="'XPath'" :value="options.XPATH2" />
</el-select>
</el-col>
@ -111,30 +63,12 @@
style="width: 120px; height: 32px"
v-model="data.option"
size="small"
:placeholder="
$t('api_test.request.assertions.select_condition')
"
>
<el-option
:label="$t('api_test.request.assertions.contains')"
value="CONTAINS"
/>
<el-option
:label="$t('api_test.request.assertions.not_contains')"
value="NOT_CONTAINS"
/>
<el-option
:label="$t('api_test.request.assertions.equals')"
value="EQUALS"
/>
<el-option
:label="$t('api_test.request.assertions.start_with')"
value="START_WITH"
/>
<el-option
:label="$t('api_test.request.assertions.end_with')"
value="END_WITH"
/>
:placeholder="$t('api_test.request.assertions.select_condition')">
<el-option :label="$t('api_test.request.assertions.contains')" value="CONTAINS" />
<el-option :label="$t('api_test.request.assertions.not_contains')" value="NOT_CONTAINS" />
<el-option :label="$t('api_test.request.assertions.equals')" value="EQUALS" />
<el-option :label="$t('api_test.request.assertions.start_with')" value="START_WITH" />
<el-option :label="$t('api_test.request.assertions.end_with')" value="END_WITH" />
</el-select>
</el-col>
<el-col>
@ -145,21 +79,16 @@
size="small"
show-word-limit
:placeholder="$t('api_test.request.assertions.value')"
width="500px"
/>
width="500px" />
</el-col>
<el-col class="assertion-btn">
<el-tooltip
:content="$t('test_resource_pool.enable_disable')"
placement="top"
>
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top">
<el-switch
v-model="data.enable"
class="enable-switch"
size="mini"
:disabled="isReadOnly"
style="width: 30px; margin-right: 10px"
/>
style="width: 30px; margin-right: 10px" />
</el-tooltip>
<el-button
@ -168,40 +97,22 @@
size="mini"
icon="el-icon-delete"
circle
@click="remove(data)"
/>
@click="remove(data)" />
</el-col>
</el-row>
</div>
<div
v-if="data.type === options.JSON_PATH"
class="assertion-item-editing"
>
<el-row
:gutter="10"
type="flex"
justify="space-between"
align="middle"
>
<div v-if="data.type === options.JSON_PATH" class="assertion-item-editing">
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
<el-col class="ms-assertion-select">
<el-select
:disabled="true"
style="width: 120px; height: 32px"
v-model="data.type"
:placeholder="
$t('api_test.request.assertions.select_type')
"
size="small"
>
<el-option
:label="$t('api_test.request.assertions.text')"
:value="options.TEXT"
/>
<el-option
:label="'JSONPath'"
:value="options.JSON_PATH"
/>
:placeholder="$t('api_test.request.assertions.select_type')"
size="small">
<el-option :label="$t('api_test.request.assertions.text')" :value="options.TEXT" />
<el-option :label="'JSONPath'" :value="options.JSON_PATH" />
<el-option :label="'XPath'" :value="options.XPATH2" />
</el-select>
</el-col>
@ -212,10 +123,7 @@
maxlength="500"
size="small"
show-word-limit
:placeholder="
$t('api_test.request.extract.json_path_expression')
"
/>
:placeholder="$t('api_test.request.extract.json_path_expression')" />
</el-col>
<el-col>
<el-select
@ -223,36 +131,14 @@
class="ms-col-type"
size="small"
style="width: 100px; margin-right: 10px"
@change="reload"
>
<el-option
:label="$t('api_test.request.assertions.contains')"
value="CONTAINS"
/>
<el-option
:label="$t('api_test.request.assertions.not_contains')"
value="NOT_CONTAINS"
/>
<el-option
:label="$t('api_test.request.assertions.equals')"
value="EQUALS"
/>
<el-option
:label="$t('commons.adv_search.operators.not_equals')"
value="NOT_EQUALS"
/>
<el-option
:label="$t('commons.adv_search.operators.gt')"
value="GT"
/>
<el-option
:label="$t('commons.adv_search.operators.lt')"
value="LT"
/>
<el-option
:label="$t('api_test.request.assertions.regular_match')"
value="REGEX"
/>
@change="reload">
<el-option :label="$t('api_test.request.assertions.contains')" value="CONTAINS" />
<el-option :label="$t('api_test.request.assertions.not_contains')" value="NOT_CONTAINS" />
<el-option :label="$t('api_test.request.assertions.equals')" value="EQUALS" />
<el-option :label="$t('commons.adv_search.operators.not_equals')" value="NOT_EQUALS" />
<el-option :label="$t('commons.adv_search.operators.gt')" value="GT" />
<el-option :label="$t('commons.adv_search.operators.lt')" value="LT" />
<el-option :label="$t('api_test.request.assertions.regular_match')" value="REGEX" />
</el-select>
<el-input
:disabled="isReadOnly"
@ -260,8 +146,7 @@
size="small"
show-word-limit
:placeholder="$t('api_test.request.assertions.expect')"
style="width: 50%"
/>
style="width: 50%" />
<el-tooltip placement="top" v-if="data.option === 'REGEX'">
<div slot="content">
{{ $t('api_test.request.assertions.regex_info') }}
@ -270,17 +155,13 @@
</el-tooltip>
</el-col>
<el-col class="assertion-btn">
<el-tooltip
:content="$t('test_resource_pool.enable_disable')"
placement="top"
>
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top">
<el-switch
v-model="data.enable"
class="enable-switch"
size="mini"
:disabled="isReadOnly"
style="width: 30px; margin-right: 10px"
/>
style="width: 30px; margin-right: 10px" />
</el-tooltip>
<el-button
:disabled="isReadOnly"
@ -288,40 +169,22 @@
size="mini"
icon="el-icon-delete"
circle
@click="remove(data)"
/>
@click="remove(data)" />
</el-col>
</el-row>
</div>
<div
v-if="data.type === options.XPATH2"
class="assertion-item-editing"
>
<el-row
:gutter="10"
type="flex"
justify="space-between"
align="middle"
>
<div v-if="data.type === options.XPATH2" class="assertion-item-editing">
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
<el-col class="ms-assertion-select">
<el-select
:disabled="true"
style="width: 120px; height: 32px"
v-model="data.type"
:placeholder="
$t('api_test.request.assertions.select_type')
"
size="small"
>
<el-option
:label="$t('api_test.request.assertions.text')"
:value="options.TEXT"
/>
<el-option
:label="'JSONPath'"
:value="options.JSON_PATH"
/>
:placeholder="$t('api_test.request.assertions.select_type')"
size="small">
<el-option :label="$t('api_test.request.assertions.text')" :value="options.TEXT" />
<el-option :label="'JSONPath'" :value="options.JSON_PATH" />
<el-option :label="'XPath'" :value="options.XPATH2" />
</el-select>
</el-col>
@ -332,23 +195,16 @@
maxlength="500"
size="small"
show-word-limit
:placeholder="
$t('api_test.request.extract.xpath_expression')
"
/>
:placeholder="$t('api_test.request.extract.xpath_expression')" />
</el-col>
<el-col class="assertion-btn">
<el-tooltip
:content="$t('test_resource_pool.enable_disable')"
placement="top"
>
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top">
<el-switch
v-model="data.enable"
class="enable-switch"
size="mini"
:disabled="isReadOnly"
style="width: 30px; margin-right: 10px"
/>
style="width: 30px; margin-right: 10px" />
</el-tooltip>
<el-button
:disabled="isReadOnly"
@ -356,8 +212,7 @@
size="mini"
icon="el-icon-delete"
circle
@click="remove(data)"
/>
@click="remove(data)" />
</el-col>
</el-row>
</div>

View File

@ -5,37 +5,28 @@
<el-icon class="el-icon-more"></el-icon>
</el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="copy" v-if="data.command">{{
this.$t('commons.copy')
}}</el-dropdown-item>
<el-dropdown-item command="copy" v-if="data.command">{{ this.$t('commons.copy') }}</el-dropdown-item>
<el-dropdown-item command="enable" v-if="data.command && data.enable"
>{{ this.$t('ui.disable') }}
</el-dropdown-item>
<el-dropdown-item command="enable" v-if="data.command && !data.enable"
>{{ this.$t('ui.enable') }}
</el-dropdown-item>
<el-dropdown-item command="remove">{{
this.$t('api_test.automation.delete_step')
}}</el-dropdown-item>
<el-dropdown-item command="remove">{{ this.$t('api_test.automation.delete_step') }}</el-dropdown-item>
<el-dropdown-item command="rename" v-if="!isScenario"
>{{ this.$t('test_track.module.rename') }}
</el-dropdown-item>
<el-dropdown-item command="scenarioVar" v-if="data.type === 'scenario'">
{{ this.$t('api_test.automation.view_scene_variables') }}
</el-dropdown-item>
<el-dropdown-item
command="openScenario"
v-if="data.type === 'scenario' && data.referenced === 'REF'"
>
<el-dropdown-item command="openScenario" v-if="data.type === 'scenario' && data.referenced === 'REF'">
{{ this.$t('api_test.automation.open_scene') }}
</el-dropdown-item>
<el-dropdown-item
command="saveAs"
v-if="
allSamplers.indexOf(data.type) != -1 &&
(data.referenced === undefined || data.referenced === 'Created')
"
>
allSamplers.indexOf(data.type) != -1 && (data.referenced === undefined || data.referenced === 'Created')
">
{{ this.$t('api_test.automation.save_as_api') }}
</el-dropdown-item>
<el-dropdown-item command="saveAsCase" v-if="data.refType === 'API'">
@ -51,22 +42,10 @@
<ms-add-api-case :currentProtocol="currentProtocol" ref="apiCase" />
<el-dialog
:title="$t('commons.reference_settings')"
:visible.sync="dialogVisible"
width="400px"
>
<el-dialog :title="$t('commons.reference_settings')" :visible.sync="dialogVisible" width="400px">
<ul>
<el-tooltip
:content="$t('commons.enable_scene_info')"
placement="top"
v-if="showEnableScenario"
>
<el-checkbox
v-model="data.environmentEnable"
@change="checkEnv"
:disabled="data.disabled"
>
<el-tooltip :content="$t('commons.enable_scene_info')" placement="top" v-if="showEnableScenario">
<el-checkbox v-model="data.environmentEnable" @change="checkEnv" :disabled="data.disabled">
{{ $t('commons.enable_scene') }}
</el-checkbox>
</el-tooltip>
@ -85,11 +64,7 @@ import MsAddBasisApi from '../api/AddBasisApi';
import MsAddApiCase from '../api/AddApiCase';
import { getUUID, strMapToObj } from 'metersphere-frontend/src/utils';
import { getCurrentProjectID } from 'metersphere-frontend/src/utils/token';
import {
checkScenarioEnv,
getScenarioWithBLOBsById,
setScenarioDomain,
} from '@/api/scenario';
import { checkScenarioEnv, getScenarioWithBLOBsById, setScenarioDomain } from '@/api/scenario';
import { hasPermission } from 'metersphere-frontend/src/utils/permission';
export default {
@ -134,11 +109,7 @@ export default {
this.$emit('remove');
break;
case 'scenarioVar':
this.$refs.scenarioParameters.open(
this.data.variables,
this.data.headers,
this.data.referenced === 'REF'
);
this.$refs.scenarioParameters.open(this.data.variables, this.data.headers, this.data.referenced === 'REF');
break;
case 'openScenario':
this.getScenario();
@ -216,11 +187,7 @@ export default {
},
setOwnEnvironment(scenarioDefinition) {
for (let i in scenarioDefinition) {
let typeArray = [
'JDBCPostProcessor',
'JDBCSampler',
'JDBCPreProcessor',
];
let typeArray = ['JDBCPostProcessor', 'JDBCSampler', 'JDBCPreProcessor'];
if (typeArray.indexOf(scenarioDefinition[i].type) !== -1) {
scenarioDefinition[i].environmentEnable = this.data.environmentEnable;
scenarioDefinition[i].refEevMap = new Map();
@ -228,10 +195,7 @@ export default {
scenarioDefinition[i].refEevMap = this.data.environmentMap;
}
}
if (
scenarioDefinition[i].hashTree &&
scenarioDefinition[i].hashTree.length > 0
) {
if (scenarioDefinition[i].hashTree && scenarioDefinition[i].hashTree.length > 0) {
this.setOwnEnvironment(scenarioDefinition[i].hashTree);
}
}

View File

@ -11,8 +11,7 @@
color="#783887"
background-color="#FCF6EE"
:if-from-variable-advance="ifFromVariableAdvance"
:title="$t('api_test.automation.transaction_controller')"
>
:title="$t('api_test.automation.transaction_controller')">
<template v-slot:debugStepCode>
<span v-if="node.data.testing" class="ms-test-running">
<i class="el-icon-loading" style="font-size: 16px" />
@ -21,8 +20,7 @@
<span
class="ms-step-debug-code"
:class="node.data.code === 'ERROR' ? 'ms-req-error' : 'ms-req-success'"
v-if="!loading && !node.data.testing && node.data.debug"
>
v-if="!loading && !node.data.testing && node.data.debug">
{{ getCode() }}
</span>
</template>
@ -33,21 +31,15 @@
size="mini"
v-model="controller.name"
style="width: 20%"
:placeholder="$t('api_test.automation.transaction_controller')"
/>
:placeholder="$t('api_test.automation.transaction_controller')" />
<el-checkbox
v-model="controller.generateParentSample"
@change="changeGenerateParantSample"
:disabled="controller.disabled"
class="ms-btn"
>
class="ms-btn">
Generate Parent Sample
</el-checkbox>
<el-checkbox
v-model="controller.includeTimers"
@change="changeIncludeTimers"
:disabled="controller.disabled"
>
<el-checkbox v-model="controller.includeTimers" @change="changeIncludeTimers" :disabled="controller.disabled">
Include Timers
</el-checkbox>
</template>
@ -170,10 +162,7 @@ export default {
},
computed: {
hasEmptyOperator() {
return (
!!this.controller.operator &&
this.controller.operator.indexOf('empty') > 0
);
return !!this.controller.operator && this.controller.operator.indexOf('empty') > 0;
},
},
};

View File

@ -1,10 +1,7 @@
export function getUrl(d) {
let url = '/#';
let resourceId = d.sourceId;
if (
resourceId &&
(resourceId.startsWith('"') || resourceId.startsWith('['))
) {
if (resourceId && (resourceId.startsWith('"') || resourceId.startsWith('['))) {
resourceId = JSON.parse(d.sourceId);
}
if (resourceId instanceof Array) {
@ -21,13 +18,7 @@ export function getUrl(d) {
url += '/api/definition?resourceId=' + resourceId;
break;
case 'CASE':
url +=
'/api/definition?caseId=' +
d.id +
'&projectId=' +
d.projectId +
'&workspaceId=' +
d.workspaceId;
url += '/api/definition?caseId=' + d.id + '&projectId=' + d.projectId + '&workspaceId=' + d.workspaceId;
break;
}
break;
@ -37,13 +28,7 @@ export function getUrl(d) {
url += '/api/definition?resourceId=' + resourceId;
break;
case 'CASE':
url +=
'/api/definition?caseId=' +
d.id +
'&projectId=' +
d.projectId +
'&workspaceId=' +
d.workspaceId;
url += '/api/definition?caseId=' + d.id + '&projectId=' + d.projectId + '&workspaceId=' + d.workspaceId;
break;
}
break;
@ -53,13 +38,7 @@ export function getUrl(d) {
url += '/api/definition?resourceId=' + resourceId;
break;
case 'CASE':
url +=
'/api/definition?caseId=' +
d.id +
'&projectId=' +
d.projectId +
'&workspaceId=' +
d.workspaceId;
url += '/api/definition?caseId=' + d.id + '&projectId=' + d.projectId + '&workspaceId=' + d.workspaceId;
break;
}
break;
@ -69,13 +48,7 @@ export function getUrl(d) {
url += '/api/definition?resourceId=' + resourceId;
break;
case 'CASE':
url +=
'/api/definition?caseId=' +
d.id +
'&projectId=' +
d.projectId +
'&workspaceId=' +
d.workspaceId;
url += '/api/definition?caseId=' + d.id + '&projectId=' + d.projectId + '&workspaceId=' + d.workspaceId;
break;
}
break;
@ -85,13 +58,7 @@ export function getUrl(d) {
url += '/api/definition?resourceId=' + resourceId;
break;
case 'CASE':
url +=
'/api/definition?caseId=' +
d.id +
'&projectId=' +
d.projectId +
'&workspaceId=' +
d.workspaceId;
url += '/api/definition?caseId=' + d.id + '&projectId=' + d.projectId + '&workspaceId=' + d.workspaceId;
break;
}
break;

View File

@ -8,32 +8,20 @@
:content="$t('test_track.case.batch_operate')"
placement="top"
effect="light"
v-show="!isBatchProcess"
>
v-show="!isBatchProcess">
<font-awesome-icon
class="ms-batch-btn"
:icon="['fa', 'bars']"
v-prevent-re-click
@click="batchProcessing"
/>
@click="batchProcessing" />
</el-tooltip>
<el-checkbox
v-show="isBatchProcess"
v-model="isCheckedAll"
@change="checkedAll"
/>
<el-tooltip
:content="$t('commons.cancel')"
placement="top"
effect="light"
v-show="isBatchProcess"
>
<el-checkbox v-show="isBatchProcess" v-model="isCheckedAll" @change="checkedAll" />
<el-tooltip :content="$t('commons.cancel')" placement="top" effect="light" v-show="isBatchProcess">
<font-awesome-icon
class="ms-batch-btn"
:icon="['fa', 'times']"
v-prevent-re-click
@click="cancelBatchProcessing"
/>
@click="cancelBatchProcessing" />
</el-tooltip>
</div>
</el-col>
@ -44,16 +32,10 @@
<el-row>
<el-col :span="8">
<el-tooltip placement="top" :content="currentScenario.name">
<span class="ms-max-scenario-name-width">{{
currentScenario.name
}}</span>
<span class="ms-max-scenario-name-width">{{ currentScenario.name }}</span>
</el-tooltip>
</el-col>
<el-col :span="8">
{{ $t('api_test.automation.step_total') }}{{
scenarioDefinition.length
}}
</el-col>
<el-col :span="8"> {{ $t('api_test.automation.step_total') }}{{ scenarioDefinition.length }} </el-col>
<el-col :span="8">
<el-link class="head" @click="showScenarioParameters"
>{{ $t('api_test.automation.scenario_total') }}
@ -64,14 +46,8 @@
</div>
</el-col>
<el-col :span="12">
<el-checkbox v-model="cookieShare" @change="setCookieShare"
>共享cookie</el-checkbox
>
<el-checkbox
v-model="sampleError"
@change="setOnSampleError"
style="margin-right: 10px"
>
<el-checkbox v-model="cookieShare" @change="setCookieShare">共享cookie</el-checkbox>
<el-checkbox v-model="sampleError" @change="setOnSampleError" style="margin-right: 10px">
{{ $t('commons.failure_continues') }}
</el-checkbox>
<env-popover
@ -88,8 +64,7 @@
ref="envPopover"
class="ms-right"
:has-option-group="true"
:result="envResult"
/>
:result="envResult" />
<el-dropdown
split-button
@ -98,55 +73,30 @@
style="margin: 0px 10px 0px"
size="mini"
@command="handleCommand"
v-show="!debugLoading"
>
v-show="!debugLoading">
{{ $t('api_test.request.debug') }}
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>{{
$t('api_test.automation.generate_report')
}}</el-dropdown-item>
<el-dropdown-item>{{ $t('api_test.automation.generate_report') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button
size="mini"
type="primary"
style="margin: 0px 10px 0px"
v-show="debugLoading"
@click="stop"
>
<el-button size="mini" type="primary" style="margin: 0px 10px 0px" v-show="debugLoading" @click="stop">
{{ $t('report.stop_btn') }}
</el-button>
</el-col>
<font-awesome-icon
class="ms-min-alt-ico"
:icon="['fa', 'compress-alt']"
size="lg"
@click="unFullScreen"
/>
<font-awesome-icon class="ms-min-alt-ico" :icon="['fa', 'compress-alt']" size="lg" @click="unFullScreen" />
</el-row>
</div>
<!-- 场景步骤-->
<ms-container :class="{ 'maximize-container': !asideHidden }">
<ms-aside-container
@setAsideHidden="setAsideHidden"
style="padding: 0px; overflow: hidden"
>
<ms-aside-container @setAsideHidden="setAsideHidden" style="padding: 0px; overflow: hidden">
<div class="ms-debug-result" v-if="reqTotal > 0">
<span style="float: right">
<span class="ms-message-right"> {{ reqTotalTime }} ms </span>
<span class="ms-message-right"
>{{ $t('api_test.automation.request_total') }}
{{ reqTotal }}</span
>
<span class="ms-message-right"
>{{ $t('api_test.automation.request_success') }}
{{ reqSuccess }}</span
>
<span class="ms-message-right">
{{ $t('api_test.automation.request_error') }} {{ reqError }}</span
>
<span class="ms-message-right">{{ $t('api_test.automation.request_total') }} {{ reqTotal }}</span>
<span class="ms-message-right">{{ $t('api_test.automation.request_success') }} {{ reqSuccess }}</span>
<span class="ms-message-right"> {{ $t('api_test.automation.request_error') }} {{ reqError }}</span>
</span>
</div>
<!-- 场景步骤内容 -->
@ -167,56 +117,35 @@
@node-drag-end="allowDrag"
@node-click="nodeClick"
class="ms-max-tree"
ref="maxStepTree"
>
ref="maxStepTree">
<el-row
class="custom-tree-node"
:gutter="18"
type="flex"
align="middle"
slot-scope="{ node, data }"
style="width: 98%"
>
style="width: 98%">
<el-col
class="custom-tree-node-col"
style="padding-left: 0px; padding-right: 0px"
v-show="
node &&
data.hashTree &&
data.hashTree.length > 0 &&
!data.isLeaf
"
>
v-show="node && data.hashTree && data.hashTree.length > 0 && !data.isLeaf">
<span
v-show="!node.expanded"
class="el-icon-circle-plus-outline custom-node_e"
@click="openOrClose(node)"
/>
<span
v-show="node.expanded"
class="el-icon-remove-outline custom-node_e"
@click="openOrClose(node)"
/>
@click="openOrClose(node)" />
<span v-show="node.expanded" class="el-icon-remove-outline custom-node_e" @click="openOrClose(node)" />
</el-col>
<!-- 批量操作 -->
<el-col
:class="
data.checkBox
? 'custom-tree-node-hide'
: 'custom-tree-node-col'
"
:class="data.checkBox ? 'custom-tree-node-hide' : 'custom-tree-node-col'"
style="padding-left: 0px; padding-right: 0px"
v-show="
(data.hashTree && data.hashTree.length === 0) || data.isLeaf
"
>
v-show="(data.hashTree && data.hashTree.length === 0) || data.isLeaf">
<show-more-btn
:is-show="node.checked"
:buttons="batchOperators"
:size="selectDataCounts"
v-show="data.checkBox"
style="margin-right: 3px"
/>
style="margin-right: 3px" />
</el-col>
<el-col>
<!-- 步骤组件-->
@ -238,20 +167,12 @@
@refReload="refReload"
@openScenario="openScenario"
v-if="
stepFilter.get('ALlSamplerStep').indexOf(data.type) ===
-1 ||
stepFilter.get('ALlSamplerStep').indexOf(data.type) === -1 ||
!node.parent ||
!node.parent.data ||
stepFilter
.get('AllSamplerProxy')
.indexOf(node.parent.data.type) === -1
"
/>
<div
v-else
class="el-tree-node is-hidden is-focusable is-leaf"
style="display: none"
>
stepFilter.get('AllSamplerProxy').indexOf(node.parent.data.type) === -1
" />
<div v-else class="el-tree-node is-hidden is-focusable is-leaf" style="display: none">
{{ hideNode(node) }}
</div>
</el-col>
@ -264,8 +185,7 @@
size="small"
:global-options="globalOptions"
:click-auto-close="false"
ref="refFab"
>
ref="refFab">
<fab-item
v-for="(item, index) in buttonData"
:key="index"
@ -275,8 +195,7 @@
:title-color="item.titleColor"
:color="item.titleColor"
:icon="item.icon"
@clickItem="item.click"
/>
@clickItem="item.click" />
</vue-fab>
</div>
</div>
@ -303,21 +222,10 @@
@suggestClick="suggestClick"
@refReload="refReload"
@openScenario="openScenario"
v-if="selectedTreeNode && selectedNode"
/>
v-if="selectedTreeNode && selectedNode" />
<!-- 请求下还有的子步骤-->
<div
v-if="
selectedTreeNode &&
selectedTreeNode.hashTree &&
showNode(selectedTreeNode)
"
>
<div
v-for="item in selectedTreeNode.hashTree"
:key="item.id"
class="ms-col-one"
>
<div v-if="selectedTreeNode && selectedTreeNode.hashTree && showNode(selectedTreeNode)">
<div v-for="item in selectedTreeNode.hashTree" :key="item.id" class="ms-col-one">
<ms-component-config
:showBtn="false"
:isMax="false"
@ -334,11 +242,8 @@
@refReload="refReload"
@openScenario="openScenario"
v-show="
selectedTreeNode &&
selectedNode &&
stepFilter.get('ALlSamplerStep').indexOf(item.type) === -1
"
/>
selectedTreeNode && selectedNode && stepFilter.get('ALlSamplerStep').indexOf(item.type) === -1
" />
</div>
</div>
</div>
@ -346,11 +251,7 @@
</ms-container>
<!--接口列表-->
<scenario-api-relevance
@save="pushApiOrCase"
ref="scenarioApiRelevance"
v-if="type !== 'detail'"
/>
<scenario-api-relevance @save="pushApiOrCase" ref="scenarioApiRelevance" v-if="type !== 'detail'" />
<!--自定义接口-->
<el-drawer
@ -362,26 +263,14 @@
:title="$t('api_test.automation.customize_req')"
style="overflow: auto"
:modal="false"
size="90%"
>
<ms-api-customize
:request="customizeRequest"
@addCustomizeApi="addCustomizeApi"
/>
size="90%">
<ms-api-customize :request="customizeRequest" @addCustomizeApi="addCustomizeApi" />
</el-drawer>
<!--场景导入 -->
<scenario-relevance
v-if="type !== 'detail'"
@save="addScenario"
ref="scenarioRelevance"
/>
<scenario-relevance v-if="type !== 'detail'" @save="addScenario" ref="scenarioRelevance" />
<!-- 环境 -->
<api-environment-config
v-if="type !== 'detail'"
ref="environmentConfig"
@close="environmentConfigClose"
/>
<api-environment-config v-if="type !== 'detail'" ref="environmentConfig" @close="environmentConfigClose" />
<!--执行组件-->
<ms-run
@ -392,8 +281,7 @@
:run-data="debugData"
@runRefresh="runRefresh"
@errorRefresh="errorRefresh"
ref="runTest"
/>
ref="runTest" />
<!-- 调试结果 -->
<el-drawer
v-if="type !== 'detail'"
@ -402,14 +290,12 @@
direction="ltr"
:withHeader="true"
:modal="false"
size="90%"
>
size="90%">
<ms-api-report-detail
:report-id="reportId"
:debug="true"
:currentProjectId="projectId"
@refresh="detailRefresh"
/>
@refresh="detailRefresh" />
</el-drawer>
<!--场景公共参数-->
@ -417,21 +303,10 @@
v-if="type !== 'detail'"
@setVariables="setVariables"
ref="scenarioParameters"
class="ms-sc-variable-header"
/>
class="ms-sc-variable-header" />
<!--外部导入-->
<api-import
v-if="type !== 'detail'"
ref="apiImport"
:saved="false"
@refresh="apiImport"
/>
<el-backtop
target=".el-main .ms-main-container"
:visibility-height="10"
:right="50"
:bottom="20"
></el-backtop>
<api-import v-if="type !== 'detail'" ref="apiImport" :saved="false" @refresh="apiImport" />
<el-backtop target=".el-main .ms-main-container" :visibility-height="10" :right="50" :bottom="20"></el-backtop>
</div>
</template>
@ -440,20 +315,11 @@ import { getApiScenarioEnv } from '@/api/scenario';
import { API_STATUS, PRIORITY } from '../../../definition/model/JsonData';
import { parseEnvironment } from '@/business/environment/model/EnvironmentModel';
import { ELEMENT_TYPE, STEP } from '../Setting';
import {
exportPdf,
getUUID,
strMapToObj,
} from 'metersphere-frontend/src/utils';
import { exportPdf, getUUID, strMapToObj } from 'metersphere-frontend/src/utils';
import { getCurrentProjectID } from 'metersphere-frontend/src/utils/token';
import { hasLicense } from 'metersphere-frontend/src/utils/permission';
import OutsideClick from '../common/outside-click';
import {
copyScenarioRow,
saveScenario,
scenarioSort,
handleCtrlSEvent,
} from '@/business/automation/api-automation';
import { copyScenarioRow, saveScenario, scenarioSort, handleCtrlSEvent } from '@/business/automation/api-automation';
import { buttons, setComponent } from '../menu/Menu';
import MsContainer from 'metersphere-frontend/src/components/MsContainer';
import MsMainContainer from 'metersphere-frontend/src/components/MsMainContainer';
@ -495,10 +361,7 @@ export default {
MsVariableList: () => import('../variable/VariableList'),
ScenarioRelevance: () => import('../api/ScenarioRelevance'),
ScenarioApiRelevance: () => import('../api/ApiRelevance'),
ApiEnvironmentConfig: () =>
import(
'metersphere-frontend/src/components/environment/ApiEnvironmentConfig'
),
ApiEnvironmentConfig: () => import('metersphere-frontend/src/components/environment/ApiEnvironmentConfig'),
MsApiReportDetail: () => import('../../report/ApiReportDetail'),
MsInputTag: () => import('../MsInputTag'),
MsRun: () => import('../DebugRun'),
@ -686,18 +549,12 @@ export default {
};
if (item.license) {
if (hasLicense()) {
if (
this.operatingElements &&
this.operatingElements.includes(item.jmeterClazz)
) {
if (this.operatingElements && this.operatingElements.includes(item.jmeterClazz)) {
this.buttonData.push(plugin);
}
}
} else {
if (
this.operatingElements &&
this.operatingElements.includes(item.jmeterClazz)
) {
if (this.operatingElements && this.operatingElements.includes(item.jmeterClazz)) {
this.buttonData.push(plugin);
}
}
@ -729,11 +586,7 @@ export default {
},
showButton(...names) {
for (const name of names) {
if (
name &&
this.operatingElements &&
this.operatingElements.includes(name)
) {
if (name && this.operatingElements && this.operatingElements.includes(name)) {
return true;
}
}
@ -750,10 +603,7 @@ export default {
},
showNode(node) {
node.active = true;
if (
node &&
this.stepFilter.get('AllSamplerProxy').indexOf(node.type) != -1
) {
if (node && this.stepFilter.get('AllSamplerProxy').indexOf(node.type) != -1) {
return true;
}
return false;
@ -765,11 +615,7 @@ export default {
this.asideHidden = data;
},
nodeClick(data, node) {
if (
data.referenced != 'REF' &&
data.referenced != 'Deleted' &&
!data.disabled
) {
if (data.referenced != 'REF' && data.referenced != 'Deleted' && !data.disabled) {
this.operatingElements = this.stepFilter.get(data.type);
} else {
this.operatingElements = [];
@ -915,32 +761,22 @@ export default {
},
remove(row, node) {
let name = row === undefined || row.name === undefined ? '' : row.name;
this.$alert(
this.$t('api_test.definition.request.delete_confirm_step') +
' ' +
name +
' ',
'',
{
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
const parent = node.parent;
const hashTree = parent.data.hashTree || parent.data;
const index = hashTree.findIndex(
(d) =>
d.resourceId != undefined &&
row.resourceId != undefined &&
d.resourceId === row.resourceId
);
hashTree.splice(index, 1);
this.sort();
this.reload();
this.initProjectIds();
}
},
}
);
this.$alert(this.$t('api_test.definition.request.delete_confirm_step') + ' ' + name + ' ', '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
const parent = node.parent;
const hashTree = parent.data.hashTree || parent.data;
const index = hashTree.findIndex(
(d) => d.resourceId != undefined && row.resourceId != undefined && d.resourceId === row.resourceId
);
hashTree.splice(index, 1);
this.sort();
this.reload();
this.initProjectIds();
}
},
});
},
copyRow(row, node) {
copyScenarioRow(row, node);
@ -1026,10 +862,7 @@ export default {
this.getEnvironments();
},
allowDrop(draggingNode, dropNode, dropType) {
if (
draggingNode.data.type === 'Assertions' ||
dropNode.data.type === 'Assertions'
) {
if (draggingNode.data.type === 'Assertions' || dropNode.data.type === 'Assertions') {
return false;
}
//
@ -1051,9 +884,7 @@ export default {
dropNode.data.referenced !== 'REF' &&
dropNode.data.referenced !== 'Deleted' &&
this.stepFilter.get(dropNode.data.type) &&
this.stepFilter
.get(dropNode.data.type)
.indexOf(draggingNode.data.type) !== -1
this.stepFilter.get(dropNode.data.type).indexOf(draggingNode.data.type) !== -1
) {
return true;
}
@ -1137,26 +968,18 @@ export default {
this.$refs['currentScenario'].validate((valid) => {
if (valid) {
this.setParameter();
saveScenario(
this.path,
this.currentScenario,
this.scenarioDefinition,
this,
(response) => {
this.$success(this.$t('commons.save_success'));
this.path = '/api/automation/update';
if (response.data) {
this.currentScenario.id = response.data.id;
}
if (this.currentScenario.tags instanceof String) {
this.currentScenario.tags = JSON.parse(
this.currentScenario.tags
);
}
this.$emit('refresh', this.currentScenario);
resolve();
saveScenario(this.path, this.currentScenario, this.scenarioDefinition, this, (response) => {
this.$success(this.$t('commons.save_success'));
this.path = '/api/automation/update';
if (response.data) {
this.currentScenario.id = response.data.id;
}
);
if (this.currentScenario.tags instanceof String) {
this.currentScenario.tags = JSON.parse(this.currentScenario.tags);
}
this.$emit('refresh', this.currentScenario);
resolve();
});
}
});
});
@ -1165,9 +988,7 @@ export default {
setParameter() {
this.currentScenario.stepTotal = this.scenarioDefinition.length;
this.currentScenario.projectId = this.projectId;
this.currentScenario.modulePath = this.getPath(
this.currentScenario.apiScenarioModuleId
);
this.currentScenario.modulePath = this.getPath(this.currentScenario.apiScenarioModuleId);
// 便
let scenario = {
id: this.currentScenario.id,
@ -1186,9 +1007,7 @@ export default {
this.currentScenario.tags = JSON.stringify(this.currentScenario.tags);
}
if (this.currentModule != null) {
this.currentScenario.modulePath = this.currentModule.method
? this.currentModule.method
: null;
this.currentScenario.modulePath = this.currentModule.method ? this.currentModule.method : null;
this.currentScenario.apiScenarioModuleId = this.currentModule.id;
}
this.currentScenario.projectId = this.projectId;
@ -1202,10 +1021,7 @@ export default {
this.loading = false;
},
showScenarioParameters() {
this.$refs.scenarioParameters.open(
this.currentScenario.variables,
this.currentScenario.headers
);
this.$refs.scenarioParameters.open(this.currentScenario.variables, this.currentScenario.headers);
},
apiImport(importData) {
if (importData && importData.data) {
@ -1221,10 +1037,7 @@ export default {
if (this.currentScenario.variables) {
size += this.currentScenario.variables.length;
}
if (
this.currentScenario.headers &&
this.currentScenario.headers.length > 1
) {
if (this.currentScenario.headers && this.currentScenario.headers.length > 1) {
size += this.currentScenario.headers.length - 1;
}
return size;
@ -1292,10 +1105,7 @@ export default {
for (let i in this.scenarioDefinition) {
if (this.scenarioDefinition[i]) {
this.scenarioDefinition[i].enable = this.stepEnable;
if (
this.scenarioDefinition[i].hashTree &&
this.scenarioDefinition[i].hashTree.length > 0
) {
if (this.scenarioDefinition[i].hashTree && this.scenarioDefinition[i].hashTree.length > 0) {
this.stepStatus(this.scenarioDefinition[i].hashTree);
}
}
@ -1336,10 +1146,7 @@ export default {
if (resourceId === nodes[i].resourceId) {
nodes.splice(i, 1);
} else {
if (
nodes[i].hashTree != undefined &&
nodes[i].hashTree.length > 0
) {
if (nodes[i].hashTree != undefined && nodes[i].hashTree.length > 0) {
this.recursionDelete(resourceId, nodes[i].hashTree);
}
}
@ -1375,18 +1182,10 @@ export default {
this.isBatchProcess = true;
this.expandedNode = [];
this.hideAllTreeNode(this.scenarioDefinition);
if (
this.$refs.maxStepTree &&
this.$refs.maxStepTree.root &&
this.$refs.maxStepTree.root.childNodes
) {
if (this.$refs.maxStepTree && this.$refs.maxStepTree.root && this.$refs.maxStepTree.root.childNodes) {
this.stepCheckedAll(true, this.$refs.maxStepTree.root.childNodes);
}
if (
this.$refs.maxStepTree &&
this.$refs.maxStepTree.root &&
this.$refs.maxStepTree.root.childNodes
) {
if (this.$refs.maxStepTree && this.$refs.maxStepTree.root && this.$refs.maxStepTree.root.childNodes) {
this.stepCheckedAll(false, this.$refs.maxStepTree.root.childNodes);
}
this.reload();
@ -1394,18 +1193,10 @@ export default {
cancelBatchProcessing() {
this.isBatchProcess = false;
this.isCheckedAll = false;
if (
this.$refs.maxStepTree &&
this.$refs.maxStepTree.root &&
this.$refs.maxStepTree.root.childNodes
) {
if (this.$refs.maxStepTree && this.$refs.maxStepTree.root && this.$refs.maxStepTree.root.childNodes) {
this.stepCheckedAll(true, this.$refs.maxStepTree.root.childNodes);
}
if (
this.$refs.maxStepTree &&
this.$refs.maxStepTree.root &&
this.$refs.maxStepTree.root.childNodes
) {
if (this.$refs.maxStepTree && this.$refs.maxStepTree.root && this.$refs.maxStepTree.root.childNodes) {
this.stepCheckedAll(false, this.$refs.maxStepTree.root.childNodes);
}
this.selectDataCounts = 0;
@ -1419,10 +1210,7 @@ export default {
let isLeaf = true;
array.forEach((item) => {
item.checkBox = false;
if (
isLeaf &&
this.stepFilter.get('ALlSamplerStep').indexOf(item.type) === -1
) {
if (isLeaf && this.stepFilter.get('ALlSamplerStep').indexOf(item.type) === -1) {
isLeaf = false;
}
if (item.hashTree && item.hashTree.length > 0) {
@ -1436,11 +1224,7 @@ export default {
}
},
checkedAll(v) {
if (
this.$refs.maxStepTree &&
this.$refs.maxStepTree.root &&
this.$refs.maxStepTree.root.childNodes
) {
if (this.$refs.maxStepTree && this.$refs.maxStepTree.root && this.$refs.maxStepTree.root.childNodes) {
this.stepCheckedAll(v, this.$refs.maxStepTree.root.childNodes);
}
},
@ -1461,10 +1245,7 @@ export default {
let row = { resourceId: 'ms-reload-max-test' };
if (this.$refs.maxStepTree && this.$refs.maxStepTree.root.data) {
this.$refs.maxStepTree.root.data.push(row);
this.$refs.maxStepTree.root.data.splice(
this.$refs.maxStepTree.root.data.length - 1,
1
);
this.$refs.maxStepTree.root.data.splice(this.$refs.maxStepTree.root.data.length - 1, 1);
}
});
},
@ -1565,8 +1346,7 @@ export default {
:deep(.el-checkbox) {
color: #303133;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
font-size: 13px;
font-weight: normal;
}
@ -1578,8 +1358,7 @@ export default {
.head {
border-bottom: 1px solid #303133;
color: #303133;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
font-size: 13px;
}
@ -1608,8 +1387,7 @@ export default {
color: #7c3985;
}
.ms-max-tree
:deep(.el-tree-node__expand-icon.expanded.el-icon-caret-right:before) {
.ms-max-tree :deep(.el-tree-node__expand-icon.expanded.el-icon-caret-right:before) {
color: #7c3985;
/* content: "\e722";*/
padding: 0;

View File

@ -148,12 +148,7 @@ export function buttons(this_) {
},
{
title: this_.$t('api_test.automation.api_list_import'),
show: this_.showButton(
'HTTPSamplerProxy',
'DubboSampler',
'JDBCSampler',
'TCPSampler'
),
show: this_.showButton('HTTPSamplerProxy', 'DubboSampler', 'JDBCSampler', 'TCPSampler'),
titleColor: '#F56C6C',
titleBgColor: '#FCF1F1',
icon: 'api',
@ -182,32 +177,20 @@ export function scenarioAssertion(data, node) {
export function setNode(_this, node) {
if (_this.selectedTreeNode) {
if (
_this.stepFilter
.get('SpecialSteps')
.indexOf(_this.selectedTreeNode.type) !== -1
) {
if (_this.stepFilter.get('SpecialSteps').indexOf(_this.selectedTreeNode.type) !== -1) {
if (_this.selectedNode.parent.data.hashTree) {
//同级请求添加断言,添加到父级
if (node.type === 'Assertions') {
scenarioAssertion(_this.selectedNode.parent.data.hashTree, node);
} else {
_this.selectedNode.parent.data.hashTree.splice(
_this.selectedTreeNode.index,
0,
node
);
_this.selectedNode.parent.data.hashTree.splice(_this.selectedTreeNode.index, 0, node);
}
} else {
//没有父级的直接加到当前的置顶
if (node.type === 'Assertions') {
scenarioAssertion(_this.scenarioDefinition, node);
} else {
_this.scenarioDefinition.splice(
_this.selectedTreeNode.index,
0,
node
);
_this.scenarioDefinition.splice(_this.selectedTreeNode.index, 0, node);
}
}
store.forceRerenderIndex = getUUID();
@ -280,16 +263,10 @@ export function setComponent(type, _this, plugin) {
);
break;
case ELEMENT_TYPE.Assertions:
setNode(
_this,
new Assertions({ label: 'SCENARIO-REF-STEP', id: getUUID() })
);
setNode(_this, new Assertions({ label: 'SCENARIO-REF-STEP', id: getUUID() }));
break;
case ELEMENT_TYPE.Extract:
setNode(
_this,
new Extract({ label: 'SCENARIO-REF-STEP', id: getUUID() })
);
setNode(_this, new Extract({ label: 'SCENARIO-REF-STEP', id: getUUID() }));
break;
case ELEMENT_TYPE.CustomizeReq:
_this.customizeRequest = {

View File

@ -1,10 +1,6 @@
<template>
<div>
<el-input
:placeholder="$t('test_track.module.search')"
v-model="condition.filterText"
size="small"
>
<el-input :placeholder="$t('test_track.module.search')" v-model="condition.filterText" size="small">
<template v-slot:append>
<el-dropdown
v-if="!isReadOnly"
@ -13,32 +9,18 @@
type="primary"
class="ms-api-button"
@click="handleCommand('add-api')"
@command="handleCommand"
>
@command="handleCommand">
<el-button icon="el-icon-folder-add" @click="addScenario"></el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="import">{{
$t('api_test.api_import.label')
}}</el-dropdown-item>
<el-dropdown-item command="export">{{
$t('report.export')
}}</el-dropdown-item>
<el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item>
<el-dropdown-item command="export">{{ $t('report.export') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-input>
<module-trash-button
v-if="!isReadOnly"
:condition="condition"
:exe="enableTrash"
/>
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash" />
<api-import
:model="'scenario'"
ref="apiImport"
:moduleOptions="moduleOptions"
@refresh="$emit('refresh')"
/>
<api-import :model="'scenario'" ref="apiImport" :moduleOptions="moduleOptions" @refresh="$emit('refresh')" />
</div>
</template>
<script>
@ -84,18 +66,16 @@ export default {
this.$warning(this.$t('commons.check_project_tip'));
return;
}
this.result = getModuleByProjectId(this.projectId).then(
(response) => {
if (response.data != undefined && response.data != null) {
this.data = response.data;
let moduleOptions = [];
this.data.forEach((node) => {
buildNodePath(node, { path: '' }, moduleOptions);
});
this.moduleOptions = moduleOptions;
}
this.result = getModuleByProjectId(this.projectId).then((response) => {
if (response.data != undefined && response.data != null) {
this.data = response.data;
let moduleOptions = [];
this.data.forEach((node) => {
buildNodePath(node, { path: '' }, moduleOptions);
});
this.moduleOptions = moduleOptions;
}
);
});
this.$refs.apiImport.open(this.currentModule);
break;
default:

View File

@ -5,8 +5,7 @@
:condition.sync="condition"
@search="initTableData"
:title="$t('test_track.plan.test_plan')"
:show-create="false"
>
:show-create="false">
</ms-table-header>
</template>
<env-popover
@ -20,8 +19,7 @@
@setEnvGroup="setEnvGroup"
ref="envPopover"
class="env-popover"
style="float: right; margin-top: 4px"
/>
style="float: right; margin-top: 4px" />
<el-table
border
class="adjust-table"
@ -29,29 +27,18 @@
@filter-change="filter"
@sort-change="sort"
@select-all="select"
@select="select"
>
@select="select">
<el-table-column type="selection" />
<el-table-column
prop="name"
:label="$t('commons.name')"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="principalName"
:label="$t('test_track.plan.plan_principal')"
show-overflow-tooltip
>
<el-table-column prop="name" :label="$t('commons.name')" show-overflow-tooltip> </el-table-column>
<el-table-column prop="principalName" :label="$t('test_track.plan.plan_principal')" show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="status"
column-key="status"
:filters="statusFilters"
:label="$t('test_track.plan.plan_status')"
show-overflow-tooltip
>
show-overflow-tooltip>
<template v-slot:default="scope">
<span @click.stop="clickt = 'stop'">
<el-dropdown class="test-case-status" @command="statusChange">
@ -61,20 +48,17 @@
<el-dropdown-menu slot="dropdown" chang>
<el-dropdown-item
:disabled="!isTestManagerOrTestUser"
:command="{ id: scope.row.id, status: 'Prepare' }"
>
:command="{ id: scope.row.id, status: 'Prepare' }">
{{ $t('test_track.plan.plan_status_prepare') }}
</el-dropdown-item>
<el-dropdown-item
:disabled="!isTestManagerOrTestUser"
:command="{ id: scope.row.id, status: 'Underway' }"
>
:command="{ id: scope.row.id, status: 'Underway' }">
{{ $t('test_track.plan.plan_status_running') }}
</el-dropdown-item>
<el-dropdown-item
:disabled="!isTestManagerOrTestUser"
:command="{ id: scope.row.id, status: 'Completed' }"
>
:command="{ id: scope.row.id, status: 'Completed' }">
{{ $t('test_track.plan.plan_status_completed') }}
</el-dropdown-item>
</el-dropdown-menu>
@ -82,18 +66,13 @@
</span>
</template>
</el-table-column>
<el-table-column
prop="projectName"
:label="$t('test_track.plan.plan_project')"
show-overflow-tooltip
>
<el-table-column prop="projectName" :label="$t('test_track.plan.plan_project')" show-overflow-tooltip>
</el-table-column>
<el-table-column
sortable
prop="plannedStartTime"
:label="$t('test_track.plan.planned_start_time')"
show-overflow-tooltip
>
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.plannedStartTime | datetimeFormat }}</span>
</template>
@ -102,8 +81,7 @@
sortable
prop="plannedEndTime"
:label="$t('test_track.plan.planned_end_time')"
show-overflow-tooltip
>
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.plannedEndTime | datetimeFormat }}</span>
</template>
@ -112,8 +90,7 @@
sortable
prop="actualStartTime"
:label="$t('test_track.plan.actual_start_time')"
show-overflow-tooltip
>
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.actualStartTime | datetimeFormat }}</span>
</template>
@ -122,8 +99,7 @@
sortable
prop="actualEndTime"
:label="$t('test_track.plan.actual_end_time')"
show-overflow-tooltip
>
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.actualEndTime | datetimeFormat }}</span>
</template>
@ -133,23 +109,16 @@
:change="initTableData"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:total="total"
/>
:total="total" />
<ms-delete-confirm
:title="$t('test_track.plan.plan_delete')"
@delete="_handleDelete"
ref="deleteConfirm"
:with-tip="enableDeleteTip"
>
:with-tip="enableDeleteTip">
{{ $t('test_track.plan.plan_delete_tip') }}
</ms-delete-confirm>
<ms-dialog-footer
style="float: right; margin: 20px"
@confirm="confirm"
@cancel="cancel"
>
</ms-dialog-footer>
<ms-dialog-footer style="float: right; margin: 20px" @confirm="confirm" @cancel="cancel"> </ms-dialog-footer>
</el-card>
</template>
@ -167,15 +136,8 @@ import { getCurrentProjectID } from 'metersphere-frontend/src/utils/token';
import { _filter, _sort } from 'metersphere-frontend/src/utils/tableUtils';
import EnvPopover from '@/business/automation/scenario/EnvPopover';
import { ENV_TYPE } from 'metersphere-frontend/src/utils/constants';
import {
getPlanStageOption,
planPage,
testPlanGetPrincipal,
} from '@/api/test-plan';
import {
getApiScenarioProjectIdByConditions,
getScenarioByProjectId,
} from '@/api/scenario';
import { getPlanStageOption, planPage, testPlanGetPrincipal } from '@/api/test-plan';
import { getApiScenarioProjectIdByConditions, getScenarioByProjectId } from '@/api/scenario';
import { getOwnerProjects } from '@/api/project';
export default {
@ -266,27 +228,14 @@ export default {
if (!sign) {
return false;
}
if (
this.environmentType === ENV_TYPE.JSON &&
(!this.projectEnvMap || this.projectEnvMap.size < 1)
) {
if (this.environmentType === ENV_TYPE.JSON && (!this.projectEnvMap || this.projectEnvMap.size < 1)) {
this.$warning(this.$t('api_test.environment.select_environment'));
return false;
} else if (
this.environmentType === ENV_TYPE.GROUP &&
!this.envGroupId
) {
} else if (this.environmentType === ENV_TYPE.GROUP && !this.envGroupId) {
this.$warning(this.$t('api_test.environment.select_environment'));
return false;
}
this.$emit(
'addTestPlan',
this.selection,
this.projectEnvMap,
this.map,
this.environmentType,
this.envGroupId
);
this.$emit('addTestPlan', this.selection, this.projectEnvMap, this.map, this.environmentType, this.envGroupId);
}
},
cancel() {
@ -342,11 +291,7 @@ export default {
return;
}
this.condition.projectId = getCurrentProjectID();
this.result = planPage(
this.currentPage,
this.pageSize,
this.condition
).then((response) => {
this.result = planPage(this.currentPage, this.pageSize, this.condition).then((response) => {
let data = response.data;
this.total = data.itemCount;
data.listObject.forEach((item) => {

View File

@ -10,8 +10,7 @@
:beforeUpload="uploadValidate"
:on-exceed="exceed"
:limit="1"
ref="upload"
>
ref="upload">
<div class="upload-default" @click.stop>
<el-popover placement="right" trigger="hover">
<div>
@ -22,11 +21,8 @@
:limit="1"
:on-exceed="exceed"
:beforeUpload="uploadValidate"
ref="uploadLocal"
>
<el-button type="text">
{{ $t('permission.project_file.local_upload') }}</el-button
>
ref="uploadLocal">
<el-button type="text"> {{ $t('permission.project_file.local_upload') }}</el-button>
<span slot="file" />
</el-upload>
</div>
@ -36,52 +32,23 @@
<i class="el-icon-plus" slot="reference" />
</el-popover>
</div>
<div
class="upload-item"
slot="file"
slot-scope="{ file }"
v-loading="loading"
>
<span>{{
file.file && file.file.name ? file.file.name : file.name
}}</span>
<span
class="el-upload-list__item-actions"
v-if="file.storage === 'FILE_REF'"
>
<span
v-if="!disabled"
class="ms-list__item-delete"
@click="handleUnlock(file)"
>
<div class="upload-item" slot="file" slot-scope="{ file }" v-loading="loading">
<span>{{ file.file && file.file.name ? file.file.name : file.name }}</span>
<span class="el-upload-list__item-actions" v-if="file.storage === 'FILE_REF'">
<span v-if="!disabled" class="ms-list__item-delete" @click="handleUnlock(file)">
<i class="el-icon-unlock" />
<span style="font-size: 13px">
{{
file.isExist
? $t('permission.project_file.file_delete_tip')
: ''
}}
{{ file.isExist ? $t('permission.project_file.file_delete_tip') : '' }}
</span>
</span>
</span>
<span class="el-upload-list__item-actions" v-else>
<span
v-if="!disabled"
class="ms-list__item-delete"
@click="handleUpload(file)"
>
<el-tooltip
:content="$t('permission.project_file.save_to_file_manage')"
placement="top"
>
<span v-if="!disabled" class="ms-list__item-delete" @click="handleUpload(file)">
<el-tooltip :content="$t('permission.project_file.save_to_file_manage')" placement="top">
<i class="el-icon-upload" style="font-size: 23px" />
</el-tooltip>
</span>
<span
v-if="!disabled"
class="ms-list__item-delete"
@click="handleRemove(file)"
>
<span v-if="!disabled" class="ms-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete" />
</span>
</span>
@ -89,9 +56,7 @@
</el-upload>
</el-col>
<el-col :span="6">
<el-button size="small" style="margin: 3px 5px" @click="download"
>下载</el-button
>
<el-button size="small" style="margin: 3px 5px" @click="download">下载</el-button>
</el-col>
</el-row>
<ms-file-batch-move ref="module" @setModuleId="setModuleId" />
@ -100,10 +65,7 @@
</template>
<script>
import {
dumpFile,
getFileMetadata,
} from 'metersphere-frontend/src/api/file-metadata';
import { dumpFile, getFileMetadata } from 'metersphere-frontend/src/api/file-metadata';
import { downloadFile, getUUID } from 'metersphere-frontend/src/utils';
import MsFileBatchMove from '@/business/commons/FileBatchMove';
import MsFileMetadataList from '@/business/commons/QuoteFileList';
@ -203,10 +165,7 @@ export default {
this.parameter.files[0].file &&
this.parameter.files[0].file.name
) {
downloadFile(
this.parameter.files[0].file.name,
this.parameter.files[0].file
);
downloadFile(this.parameter.files[0].file.name, this.parameter.files[0].file);
}
//
if (
@ -238,33 +197,26 @@ export default {
},
handleRemove(file) {
let fileName = file.name ? file.name : file.file.name;
this.$alert(
this.$t('api_test.environment.csv_delete') +
':【 ' +
fileName +
' 】?',
'',
{
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
this.$refs.upload.handleRemove(file);
this.$refs.uploadLocal.handleRemove(file);
for (let i = 0; i < this.parameter.files.length; i++) {
let paramFileName = this.parameter.files[i].name
? this.parameter.files[i].name
: this.parameter.files[i].file.name;
if (fileName === paramFileName) {
this.parameter.files.splice(i, 1);
this.$refs.upload.handleRemove(file);
this.$refs.uploadLocal.handleRemove(file);
break;
}
this.$alert(this.$t('api_test.environment.csv_delete') + ':【 ' + fileName + ' 】?', '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
this.$refs.upload.handleRemove(file);
this.$refs.uploadLocal.handleRemove(file);
for (let i = 0; i < this.parameter.files.length; i++) {
let paramFileName = this.parameter.files[i].name
? this.parameter.files[i].name
: this.parameter.files[i].file.name;
if (fileName === paramFileName) {
this.parameter.files.splice(i, 1);
this.$refs.upload.handleRemove(file);
this.$refs.uploadLocal.handleRemove(file);
break;
}
}
},
}
);
}
},
});
},
exceed() {
this.$warning(this.$t('test_track.case.import.upload_limit_count'));

View File

@ -7,14 +7,9 @@
size="small"
ref="form"
:rules="rules"
:key="isActive"
>
:key="isActive">
<el-form-item :label="$t('api_test.variable_name')" prop="name">
<el-input
v-model="editData.name"
:placeholder="$t('api_test.variable_name')"
ref="nameInput"
/>
<el-input v-model="editData.name" :placeholder="$t('api_test.variable_name')" ref="nameInput" />
</el-form-item>
<el-form-item :label="$t('commons.description')" prop="description">
@ -25,8 +20,7 @@
:autosize="{ minRows: 2, maxRows: 10 }"
:rows="2"
size="small"
:disabled="disabled"
/>
:disabled="disabled" />
</el-form-item>
<el-form-item :label="$t('api_test.value')" prop="value">
@ -39,30 +33,18 @@
v-model="editData.value"
value-key="name"
:fetch-suggestions="funcSearch"
highlight-first-item
>
<i
slot="suffix"
class="el-input__icon el-icon-edit pointer"
@click="advanced(editData.value)"
></i>
highlight-first-item>
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced(editData.value)"></i>
</el-autocomplete>
</el-col>
</el-form-item>
</el-form>
<ms-api-variable-advance
ref="variableAdvance"
:current-item.sync="editData"
@advancedRefresh="reload"
/>
<ms-api-variable-advance ref="variableAdvance" :current-item.sync="editData" @advancedRefresh="reload" />
</div>
</template>
<script>
import {
JMETER_FUNC,
MOCKJS_FUNC,
} from 'metersphere-frontend/src/utils/constants';
import { JMETER_FUNC, MOCKJS_FUNC } from 'metersphere-frontend/src/utils/constants';
import MsApiVariableAdvance from 'metersphere-frontend/src/components/environment/commons/ApiVariableAdvance';
export default {
@ -98,9 +80,7 @@ export default {
},
createFilter(queryString) {
return (variable) => {
return (
variable.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
return variable.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
};
},
funcFilter(queryString) {
@ -110,9 +90,7 @@ export default {
},
funcSearch(queryString, cb) {
let func = MOCKJS_FUNC.concat(JMETER_FUNC);
let results = queryString
? func.filter(this.funcFilter(queryString))
: func;
let results = queryString ? func.filter(this.funcFilter(queryString)) : func;
// callback
cb(results);
},

View File

@ -1,17 +1,7 @@
<template>
<el-form
:model="editData"
label-position="right"
label-width="80px"
size="small"
ref="form2"
:rules="rules"
>
<el-form :model="editData" label-position="right" label-width="80px" size="small" ref="form2" :rules="rules">
<el-form-item :label="$t('api_test.variable_name')" prop="name">
<el-input
v-model="editData.name"
:placeholder="$t('api_test.variable_name')"
></el-input>
<el-input v-model="editData.name" :placeholder="$t('api_test.variable_name')"></el-input>
</el-form-item>
<el-form-item :label="$t('commons.description')" prop="description">
@ -22,8 +12,7 @@
:autosize="{ minRows: 2, maxRows: 10 }"
:rows="2"
size="small"
:disabled="disabled"
/>
:disabled="disabled" />
</el-form-item>
<el-form-item :label="$t('variables.start')" prop="startNumber">
@ -34,8 +23,7 @@
placeholder="0"
style="width: 100%"
:max="1000 * 10000000"
:min="0"
/>
:min="0" />
</el-form-item>
<el-form-item :label="$t('variables.end')" prop="endNumber">
<el-input-number
@ -45,8 +33,7 @@
placeholder="10"
style="width: 100%"
:max="1000 * 10000000"
:min="0"
/>
:min="0" />
</el-form-item>
<el-form-item :label="$t('variables.increment')" prop="increment">
<el-input-number
@ -56,15 +43,10 @@
placeholder="1"
style="width: 100%"
:max="1000 * 10000000"
:min="0"
/>
:min="0" />
</el-form-item>
<el-form-item :label="$t('variables.format')" prop="value">
<el-input
:disabled="disabled"
v-model="editData.value"
:placeholder="$t('variables.counter_info')"
></el-input>
<el-input :disabled="disabled" v-model="editData.value" :placeholder="$t('variables.counter_info')"></el-input>
</el-form-item>
</el-form>
</template>

View File

@ -1,17 +1,7 @@
<template>
<el-form
:model="editData"
label-position="right"
label-width="80px"
size="small"
ref="form3"
:rules="rules"
>
<el-form :model="editData" label-position="right" label-width="80px" size="small" ref="form3" :rules="rules">
<el-form-item :label="$t('api_test.variable_name')" prop="name">
<el-input
v-model="editData.name"
:placeholder="$t('api_test.variable_name')"
></el-input>
<el-input v-model="editData.name" :placeholder="$t('api_test.variable_name')"></el-input>
</el-form-item>
<el-form-item :label="$t('commons.description')" prop="description">
@ -23,14 +13,9 @@
:placeholder="$t('commons.input_content')"
:autosize="{ minRows: 2, maxRows: 10 }"
:rows="2"
size="small"
/>
size="small" />
</el-form-item>
<el-tabs
v-model="activeName"
@tab-click="handleClick"
style="margin-left: 40px"
>
<el-tabs v-model="activeName" @tab-click="handleClick" style="margin-left: 40px">
<el-tab-pane :label="$t('variables.config')" name="config">
<el-row>
<el-col :span="5" style="margin-top: 5px">
@ -51,8 +36,7 @@
v-model="editData.encoding"
:disabled="disabled"
:fetch-suggestions="querySearch"
:placeholder="$t('commons.input_content')"
></el-autocomplete>
:placeholder="$t('commons.input_content')"></el-autocomplete>
</el-col>
</el-row>
<el-row style="margin-top: 10px">
@ -60,11 +44,7 @@
<span>{{ $t('variables.delimiter') }}</span>
</el-col>
<el-col :span="19">
<el-input
v-model="editData.delimiter"
size="small"
:disabled="disabled"
/>
<el-input v-model="editData.delimiter" size="small" :disabled="disabled" />
</el-col>
</el-row>
<el-row style="margin-top: 10px">
@ -72,11 +52,7 @@
<span>{{ $t('variables.quoted_data') }}</span>
</el-col>
<el-col :span="19">
<el-select
v-model="editData.quotedData"
size="small"
:disabled="disabled"
>
<el-select v-model="editData.quotedData" size="small" :disabled="disabled">
<el-option label="true" :value="true" />
<el-option label="false" :value="false" />
</el-select>
@ -85,20 +61,14 @@
</el-tab-pane>
<el-tab-pane :label="$t('schema.preview')" name="preview">
<div v-if="showMessage">{{ $t('variables.csv_message') }}</div>
<el-table
:data="previewData"
style="width: 100%"
height="200px"
v-loading="loading"
>
<el-table :data="previewData" style="width: 100%" height="200px" v-loading="loading">
<!-- 自定义列的遍历-->
<el-table-column
v-for="(item, index) in columns"
:key="index"
:label="columns[index]"
align="left"
width="180"
>
width="180">
<!-- 数据的遍历 scope.row就代表数据的每一个对象-->
<template slot-scope="scope">
<span>{{ scope.row[index] }}</span>
@ -227,10 +197,7 @@ export default {
},
createFilter(queryString) {
return (restaurant) => {
return (
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) ===
0
);
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
};
},
@ -242,9 +209,7 @@ export default {
{ value: 'ISO-8859-15' },
{ value: 'US-ASCll' },
];
let results = queryString
? restaurants.filter(this.createFilter(queryString))
: restaurants;
let results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
// callback
cb(results);
},

View File

@ -1,17 +1,7 @@
<template>
<el-form
:model="editData"
label-position="right"
label-width="80px"
size="small"
ref="form4"
:rules="rules"
>
<el-form :model="editData" label-position="right" label-width="80px" size="small" ref="form4" :rules="rules">
<el-form-item :label="$t('api_test.variable_name')" prop="name">
<el-input
v-model="editData.name"
:placeholder="$t('api_test.variable_name')"
></el-input>
<el-input v-model="editData.name" :placeholder="$t('api_test.variable_name')"></el-input>
</el-form-item>
<el-form-item :label="$t('commons.description')" prop="description">
@ -22,16 +12,11 @@
:autosize="{ minRows: 2, maxRows: 10 }"
:rows="2"
size="small"
:disabled="disabled"
/>
:disabled="disabled" />
</el-form-item>
<el-form-item :label="$t('api_test.value')" prop="value">
<el-input
v-model="editData.value"
:disabled="disabled"
placeholder="列表数据用,分隔"
/>
<el-input v-model="editData.value" :disabled="disabled" placeholder="列表数据用,分隔" />
</el-form-item>
</el-form>
</template>

View File

@ -1,17 +1,7 @@
<template>
<el-form
:model="editData"
label-position="right"
label-width="80px"
size="small"
ref="form5"
:rules="rules"
>
<el-form :model="editData" label-position="right" label-width="80px" size="small" ref="form5" :rules="rules">
<el-form-item :label="$t('api_test.variable_name')" prop="name">
<el-input
v-model="editData.name"
:placeholder="$t('api_test.variable_name')"
></el-input>
<el-input v-model="editData.name" :placeholder="$t('api_test.variable_name')"></el-input>
</el-form-item>
<el-form-item :label="$t('commons.description')" prop="description">
@ -22,32 +12,17 @@
:disabled="disabled"
:autosize="{ minRows: 2, maxRows: 10 }"
:rows="2"
size="small"
/>
size="small" />
</el-form-item>
<el-form-item :label="$t('schema.minimum')" prop="minNumber">
<el-input
:disabled="disabled"
size="small"
v-model="editData.minNumber"
placeholder="0"
/>
<el-input :disabled="disabled" size="small" v-model="editData.minNumber" placeholder="0" />
</el-form-item>
<el-form-item :label="$t('schema.maximum')" prop="maxNumber">
<el-input
:disabled="disabled"
size="small"
v-model="editData.maxNumber"
placeholder="10"
/>
<el-input :disabled="disabled" size="small" v-model="editData.maxNumber" placeholder="10" />
</el-form-item>
<el-form-item :label="$t('variables.format')" prop="value">
<el-input
:disabled="disabled"
v-model="editData.value"
:placeholder="$t('variables.counter_info')"
></el-input>
<el-input :disabled="disabled" v-model="editData.value" :placeholder="$t('variables.counter_info')"></el-input>
</el-form-item>
</el-form>
</template>

View File

@ -5,17 +5,11 @@
@close="close"
:close-on-click-modal="false"
append-to-body
width="35%"
>
width="35%">
<el-form :rules="rules" label-width="80px" v-model="modeId">
<el-form-item prop="modeId" :label="$t('commons.import_mode')">
<el-select size="small" v-model="modeId">
<el-option
v-for="item in modeOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
@ -30,13 +24,9 @@
:on-remove="handleRemove"
:on-exceed="handleExceed"
:auto-upload="false"
accept=".json"
>
accept=".json">
<i class="el-icon-upload"></i>
<div
class="el-upload__text"
v-html="$t('load_test.upload_tips')"
></div>
<div class="el-upload__text" v-html="$t('load_test.upload_tips')"></div>
<div class="el-upload__tip" slot="tip">
{{ $t('api_test.api_import.file_size_limit') }}
{{ '' + $t('api_test.api_import.ms_env_import_file_limit') }}
@ -132,9 +122,7 @@ export default {
this.dialogVisible = false;
this.$success(this.$t('commons.save_success'));
} catch (exception) {
this.$warning(
this.$t('api_test.api_import.ms_env_import_file_limit')
);
this.$warning(this.$t('api_test.api_import.ms_env_import_file_limit'));
}
};
}

View File

@ -7,15 +7,11 @@
width="80%"
@close="close"
v-loading="loading"
append-to-body
>
append-to-body>
<fieldset :disabled="disabled" class="ms-fieldset">
<el-collapse-transition>
<el-tabs v-model="activeName" @tab-click="reloadTable">
<el-tab-pane
:label="$t('api_test.scenario.variables')"
name="variable"
>
<el-tab-pane :label="$t('api_test.scenario.variables')" name="variable">
<div>
<el-row style="margin-bottom: 10px">
<div style="float: left">
@ -24,36 +20,19 @@
v-model="selectVariable"
size="small"
@change="filter"
@keyup.enter="filter"
>
@keyup.enter="filter">
<el-select
v-model="searchType"
slot="prepend"
:placeholder="$t('test_resource_pool.type')"
style="width: 90px"
@change="filter"
>
<el-option
value="ALL"
:label="$t('api_test.automation.all')"
></el-option>
<el-option
value="CONSTANT"
:label="$t('api_test.automation.constant')"
></el-option>
<el-option
value="LIST"
:label="$t('test_track.case.list')"
></el-option>
@change="filter">
<el-option value="ALL" :label="$t('api_test.automation.all')"></el-option>
<el-option value="CONSTANT" :label="$t('api_test.automation.constant')"></el-option>
<el-option value="LIST" :label="$t('test_track.case.list')"></el-option>
<el-option value="CSV" label="CSV"></el-option>
<el-option
value="COUNTER"
:label="$t('api_test.automation.counter')"
></el-option>
<el-option
value="RANDOM"
:label="$t('api_test.automation.random')"
></el-option>
<el-option value="COUNTER" :label="$t('api_test.automation.counter')"></el-option>
<el-option value="RANDOM" :label="$t('api_test.automation.random')"></el-option>
</el-select>
</el-input>
</div>
@ -64,58 +43,29 @@
:placeholder="$t('test_resource_pool.type')"
style="width: 90px"
size="small"
@change="filter"
>
<el-option
value="CONSTANT"
:label="$t('api_test.automation.constant')"
></el-option>
<el-option
value="LIST"
:label="$t('test_track.case.list')"
></el-option>
@change="filter">
<el-option value="CONSTANT" :label="$t('api_test.automation.constant')"></el-option>
<el-option value="LIST" :label="$t('test_track.case.list')"></el-option>
<el-option value="CSV" label="CSV"></el-option>
<el-option
value="COUNTER"
:label="$t('api_test.automation.counter')"
></el-option>
<el-option
value="RANDOM"
:label="$t('api_test.automation.random')"
></el-option>
<el-option value="COUNTER" :label="$t('api_test.automation.counter')"></el-option>
<el-option value="RANDOM" :label="$t('api_test.automation.random')"></el-option>
</el-select>
<el-button
size="small"
style="margin-left: 10px"
type="primary"
@click="addVariable"
>
<el-button size="small" style="margin-left: 10px" type="primary" @click="addVariable">
{{ $t('commons.add') }}
</el-button>
<el-dropdown style="margin-left: 10px">
<el-button size="small">
<span class="tip-font">{{
$t('commons.more_operator')
}}</span>
<span class="tip-font">{{ $t('commons.more_operator') }}</span>
<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
@click.native.stop="importVariable"
:disabled="disabled"
>
<el-dropdown-item @click.native.stop="importVariable" :disabled="disabled">
{{ $t('commons.import_variable') }}
</el-dropdown-item>
<el-dropdown-item
@click.native.stop="exportVariable"
:disabled="disabled"
>
<el-dropdown-item @click.native.stop="exportVariable" :disabled="disabled">
{{ $t('commons.export_variable') }}
</el-dropdown-item>
<el-dropdown-item
@click.native.stop="batchAddParameter"
:disabled="disabled"
>
<el-dropdown-item @click.native.stop="batchAddParameter" :disabled="disabled">
{{ $t('commons.batch_add') }}
</el-dropdown-item>
</el-dropdown-menu>
@ -124,14 +74,7 @@
</el-row>
<el-row>
<el-col :span="12">
<div
style="
border: 1px #dcdfe6 solid;
min-height: 400px;
border-radius: 4px;
width: 100%;
"
>
<div style="border: 1px #dcdfe6 solid; min-height: 400px; border-radius: 4px; width: 100%">
<ms-table
v-loading="loading"
row-key="id"
@ -145,8 +88,7 @@
:field-key="tableHeaderKey"
@handleRowClick="handleRowClick"
@refresh="onChange"
ref="variableTable"
>
ref="variableTable">
<span v-for="item in fields" :key="item.key">
<ms-table-column
prop="num"
@ -154,8 +96,7 @@
:fields-width="fieldsWidth"
sortable
label="ID"
min-width="60"
>
min-width="60">
</ms-table-column>
<ms-table-column
prop="name"
@ -163,8 +104,7 @@
:fields-width="fieldsWidth"
:label="$t('api_test.variable_name')"
min-width="100"
sortable
>
sortable>
</ms-table-column>
<ms-table-column
prop="type"
@ -172,8 +112,7 @@
:fields-width="fieldsWidth"
:label="$t('test_track.case.type')"
min-width="70"
sortable
>
sortable>
<template v-slot:default="scope">
<span>{{ types.get(scope.row.type) }}</span>
</template>
@ -183,8 +122,7 @@
:field="item"
:fields-width="fieldsWidth"
:label="$t('api_test.value')"
sortable
>
sortable>
</ms-table-column>
<ms-table-column
prop="description"
@ -192,64 +130,27 @@
:fields-width="fieldsWidth"
:label="$t('commons.description')"
min-width="70"
sortable
>
sortable>
</ms-table-column>
</span>
</ms-table>
<batch-add-parameter
@batchSave="batchSaveParameter"
ref="batchAddParameter"
/>
<batch-add-parameter @batchSave="batchSaveParameter" ref="batchAddParameter" />
</div>
</el-col>
<el-col :span="12">
<ms-edit-constant
v-if="editData.type == 'CONSTANT'"
ref="parameters"
:editData.sync="editData"
/>
<ms-edit-counter
v-if="editData.type == 'COUNTER'"
ref="counter"
:editData.sync="editData"
/>
<ms-edit-random
v-if="editData.type == 'RANDOM'"
ref="random"
:editData.sync="editData"
/>
<ms-edit-list-value
v-if="editData.type == 'LIST'"
ref="listValue"
:editData="editData"
/>
<ms-edit-csv
v-if="editData.type === 'CSV' && !loading"
ref="csv"
:editData.sync="editData"
/>
<ms-edit-constant v-if="editData.type == 'CONSTANT'" ref="parameters" :editData.sync="editData" />
<ms-edit-counter v-if="editData.type == 'COUNTER'" ref="counter" :editData.sync="editData" />
<ms-edit-random v-if="editData.type == 'RANDOM'" ref="random" :editData.sync="editData" />
<ms-edit-list-value v-if="editData.type == 'LIST'" ref="listValue" :editData="editData" />
<ms-edit-csv v-if="editData.type === 'CSV' && !loading" ref="csv" :editData.sync="editData" />
<div v-if="editData.type" style="float: right">
<el-button
size="small"
style="margin-left: 10px"
type="primary"
@click="confirmVariable"
>
<el-button size="small" style="margin-left: 10px" type="primary" @click="confirmVariable">
{{ $t('commons.confirm') }}
</el-button>
<el-button
size="small"
style="margin-left: 10px"
@click="cancelVariable"
<el-button size="small" style="margin-left: 10px" @click="cancelVariable"
>{{ $t('commons.cancel') }}
</el-button>
<el-button
v-if="showDelete"
size="small"
style="margin-left: 10px"
@click="deleteVariable"
>
<el-button v-if="showDelete" size="small" style="margin-left: 10px" @click="deleteVariable">
{{ $t('commons.delete') }}
</el-button>
</div>
@ -264,14 +165,10 @@
effect="dark"
:content="$t('api_test.request.headers')"
placement="top-start"
slot="label"
>
slot="label">
<span
>{{ $t('api_test.request.headers') }}
<div
class="el-step__icon is-text ms-api-col ms-header"
v-if="headers.length > 1"
>
<div class="el-step__icon is-text ms-api-col ms-header" v-if="headers.length > 1">
<div class="el-step__icon-inner">
{{ headers.length - 1 }}
</div>
@ -279,40 +176,24 @@
</span>
</el-tooltip>
<el-row>
<el-link
class="ms-variable-link"
@click="batchAddHeader"
type="primary"
:disabled="disabled"
>
<el-link class="ms-variable-link" @click="batchAddHeader" type="primary" :disabled="disabled">
{{ $t('commons.batch_add') }}
</el-link>
</el-row>
<div style="min-height: 400px">
<ms-api-key-value
:items="headers"
:suggestions="headerSuggestions"
/>
<batch-add-parameter
@batchSave="batchSaveHeader"
ref="batchAddHeader"
/>
<ms-api-key-value :items="headers" :suggestions="headerSuggestions" />
<batch-add-parameter @batchSave="batchSaveHeader" ref="batchAddHeader" />
</div>
</el-tab-pane>
</el-tabs>
<template v-slot:footer>
<div>
<el-button type="primary" @click="save">{{
$t('commons.confirm')
}}</el-button>
<el-button type="primary" @click="save">{{ $t('commons.confirm') }}</el-button>
</div>
</template>
</el-collapse-transition>
</fieldset>
<variable-import
ref="variableImport"
@mergeData="mergeData"
></variable-import>
<variable-import ref="variableImport" @mergeData="mergeData"></variable-import>
</el-dialog>
</template>
@ -333,10 +214,7 @@ import { REQUEST_HEADERS } from 'metersphere-frontend/src/utils/constants';
import MsTable from 'metersphere-frontend/src/components/table/MsTable';
import MsTableColumn from 'metersphere-frontend/src/components/table/MsTableColumn';
import {
getCustomTableHeader,
getCustomTableWidth,
} from 'metersphere-frontend/src/utils/tableUtils';
import { getCustomTableHeader, getCustomTableWidth } from 'metersphere-frontend/src/utils/tableUtils';
import VariableImport from '@/business/automation/scenario/variable/VariableImport';
const jsondiffpatch = require('jsondiffpatch');
@ -412,9 +290,7 @@ export default {
importData.id = getUUID();
importData.enable = true;
importData.showMore = false;
let sameNameIndex = this.variables.findIndex(
(d) => d.name === importData.name
);
let sameNameIndex = this.variables.findIndex((d) => d.name === importData.name);
if (sameNameIndex !== -1) {
if (modeId === 'fullCoverage') {
this.variables.splice(sameNameIndex, 1, importData);
@ -445,10 +321,7 @@ export default {
this.$warning(messages);
return;
}
downloadFile(
'MS_' + variablesJson.length + '_Environments_variables.json',
JSON.stringify(variablesJson)
);
downloadFile('MS_' + variablesJson.length + '_Environments_variables.json', JSON.stringify(variablesJson));
},
batchAddParameter() {
this.$refs.batchAddParameter.open('scenario');
@ -620,14 +493,8 @@ export default {
this.selectType = 'CONSTANT';
this.editData = {};
if (
jsondiffpatch.diff(
JSON.parse(JSON.stringify(this.variables)),
this.variablesOld
) ||
jsondiffpatch.diff(
JSON.parse(JSON.stringify(this.headers)),
this.headersOld
)
jsondiffpatch.diff(JSON.parse(JSON.stringify(this.variables)), this.variablesOld) ||
jsondiffpatch.diff(JSON.parse(JSON.stringify(this.headers)), this.headersOld)
) {
this.$emit('setVariables', saveVariables, this.headers);
}
@ -654,11 +521,7 @@ export default {
});
if (repeatKey !== '') {
this.$warning(
this.$t('api_test.scenario.variables') +
'【' +
repeatKey +
'】' +
this.$t('load_test.param_is_duplicate')
this.$t('api_test.scenario.variables') + '【' + repeatKey + '】' + this.$t('load_test.param_is_duplicate')
);
return;
}
@ -706,26 +569,19 @@ export default {
});
if (message !== '') {
message = message.substr(0, message.length - 1);
this.$alert(
this.$t('api_test.environment.variables_delete_info') +
':【 ' +
message +
' 】?',
'',
{
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
ids.forEach((row) => {
const index = this.variables.findIndex((d) => d.id === row);
this.variables.splice(index, 1);
});
this.sortParameters();
this.editData = {};
}
},
}
);
this.$alert(this.$t('api_test.environment.variables_delete_info') + ':【 ' + message + ' 】?', '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
ids.forEach((row) => {
const index = this.variables.findIndex((d) => d.id === row);
this.variables.splice(index, 1);
});
this.sortParameters();
this.editData = {};
}
},
});
} else {
ids.forEach((row) => {
const index = this.variables.findIndex((d) => d.id === row);
@ -736,58 +592,40 @@ export default {
}
},
handleDeleteBatch() {
this.$alert(
this.$t('api_test.environment.variables_delete_info') + ' ' + ' ',
'',
{
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
let ids = this.$refs.variableTable.selectIds;
ids.forEach((row) => {
const index = this.variables.findIndex((d) => d.id === row);
this.variables.splice(index, 1);
});
// this.editData = {type: "CONSTANT"};
this.sortParameters();
this.editData = {};
this.$refs.variableTable.cancelCurrentRow();
this.$refs.variableTable.clear();
}
},
}
);
this.$alert(this.$t('api_test.environment.variables_delete_info') + ' ' + ' ', '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
let ids = this.$refs.variableTable.selectIds;
ids.forEach((row) => {
const index = this.variables.findIndex((d) => d.id === row);
this.variables.splice(index, 1);
});
// this.editData = {type: "CONSTANT"};
this.sortParameters();
this.editData = {};
this.$refs.variableTable.cancelCurrentRow();
this.$refs.variableTable.clear();
}
},
});
},
filter() {
let data = [];
this.variables.forEach((item) => {
if (
this.searchType &&
this.searchType != '' &&
this.selectVariable &&
this.selectVariable != ''
) {
if (this.searchType && this.searchType != '' && this.selectVariable && this.selectVariable != '') {
if (
(item.type &&
item.type.toLowerCase().indexOf(this.searchType.toLowerCase()) ==
-1 &&
item.type.toLowerCase().indexOf(this.searchType.toLowerCase()) == -1 &&
this.searchType != 'ALL') ||
(item.name &&
item.name
.toLowerCase()
.indexOf(this.selectVariable.toLowerCase()) == -1)
(item.name && item.name.toLowerCase().indexOf(this.selectVariable.toLowerCase()) == -1)
) {
item.hidden = true;
} else {
item.hidden = undefined;
}
} else if (this.selectVariable && this.selectVariable != '') {
if (
item.name &&
item.name
.toLowerCase()
.indexOf(this.selectVariable.toLowerCase()) == -1
) {
if (item.name && item.name.toLowerCase().indexOf(this.selectVariable.toLowerCase()) == -1) {
item.hidden = true;
} else {
item.hidden = undefined;
@ -795,8 +633,7 @@ export default {
} else if (this.searchType && this.searchType != '') {
if (
item.type &&
item.type.toLowerCase().indexOf(this.searchType.toLowerCase()) ==
-1 &&
item.type.toLowerCase().indexOf(this.searchType.toLowerCase()) == -1 &&
this.searchType != 'ALL'
) {
item.hidden = true;
@ -806,10 +643,7 @@ export default {
} else {
item.hidden = undefined;
}
if (
this.searchType === 'ALL' &&
!(this.selectVariable && this.selectVariable != '')
) {
if (this.searchType === 'ALL' && !(this.selectVariable && this.selectVariable != '')) {
item.hidden = undefined;
}
data.push(item);
@ -818,10 +652,7 @@ export default {
},
createFilter(queryString) {
return (item) => {
return (
item.type &&
item.type.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
);
return item.type && item.type.toLowerCase().indexOf(queryString.toLowerCase()) !== -1;
};
},
handleRowClick(row) {

View File

@ -5,8 +5,7 @@
class="schedule-edit"
:visible.sync="dialogVisible"
:append-to-body="true"
@close="close"
>
@close="close">
<template>
<div v-loading="loading">
<el-tabs v-model="activeName">
@ -15,18 +14,8 @@
<div class="el-step__icon-inner">1</div>
</div>
<span>{{ $t('schedule.edit_timer_task') }}</span>
<el-form
:model="form"
:rules="rules"
ref="from"
style="margin-top: 10px"
class="ms-el-form-item__error"
>
<el-form-item
:label="$t('commons.schedule_cron_title')"
prop="cronValue"
style="height: 50px"
>
<el-form :model="form" :rules="rules" ref="from" style="margin-top: 10px" class="ms-el-form-item__error">
<el-form-item :label="$t('commons.schedule_cron_title')" prop="cronValue" style="height: 50px">
<el-row :gutter="20">
<el-col :span="16">
<el-input
@ -34,14 +23,8 @@
v-model="form.cronValue"
class="inp"
:placeholder="$t('schedule.please_input_cron_expression')"
size="mini"
>
<a
:disabled="isReadOnly"
@click="showCronDialog"
slot="suffix"
class="head"
>
size="mini">
<a :disabled="isReadOnly" @click="showCronDialog" slot="suffix" class="head">
{{ $t('schedule.generate_expression') }}
</a>
</el-input>
@ -50,24 +33,12 @@
<el-tooltip
effect="dark"
placement="bottom"
:content="
schedule.enable
? $t('commons.close_schedule')
: $t('commons.open_schedule')
"
>
<el-switch
v-model="schedule.enable"
style="margin-left: 20px"
></el-switch>
:content="schedule.enable ? $t('commons.close_schedule') : $t('commons.open_schedule')">
<el-switch v-model="schedule.enable" style="margin-left: 20px"></el-switch>
</el-tooltip>
</el-col>
<el-col :span="2">
<el-button
:disabled="isReadOnly"
type="primary"
@click="saveCron"
size="mini"
<el-button :disabled="isReadOnly" type="primary" @click="saveCron" size="mini"
>{{ $t('commons.save') }}
</el-button>
</el-col>
@ -80,9 +51,7 @@
</div>
<span>{{ $t('load_test.runtime_config') }}</span>
<div style="padding-top: 10px">
<span class="ms-mode-span"
>{{ $t('commons.environment') }}</span
>
<span class="ms-mode-span">{{ $t('commons.environment') }}</span>
<env-popover
:project-ids="projectIds"
:placement="'bottom-start'"
@ -95,55 +64,34 @@
@setProjectEnvMap="setProjectEnvMap"
@showPopover="showPopover"
ref="envPopover"
class="env-popover"
/>
class="env-popover" />
</div>
<div class="ms-mode-div">
<span class="ms-mode-span"
>{{ $t('run_mode.other_config') }}</span
>
<el-checkbox
v-model="runConfig.runWithinResourcePool"
:disabled="runMode === 'POOL'"
>
<span class="ms-mode-span">{{ $t('run_mode.other_config') }}</span>
<el-checkbox v-model="runConfig.runWithinResourcePool" :disabled="runMode === 'POOL'">
{{ $t('run_mode.run_with_resource_pool') }}
</el-checkbox>
<el-select
style="margin-left: 10px"
:disabled="!runConfig.runWithinResourcePool"
v-model="runConfig.resourcePoolId"
size="mini"
>
size="mini">
<el-option
v-for="item in resourcePools"
:key="item.id"
:label="item.name"
:disabled="!item.api"
:value="item.id"
>
:value="item.id">
</el-option>
</el-select>
</div>
<el-dialog
width="60%"
:title="$t('schedule.generate_expression')"
:visible.sync="showCron"
:modal="false"
>
<crontab
@hide="showCron = false"
@fill="crontabFill"
:expression="schedule.value"
ref="crontab"
/>
<el-dialog width="60%" :title="$t('schedule.generate_expression')" :visible.sync="showCron" :modal="false">
<crontab @hide="showCron = false" @fill="crontabFill" :expression="schedule.value" ref="crontab" />
</el-dialog>
</el-tab-pane>
<el-tab-pane :label="$t('schedule.task_notification')" name="second">
<ms-schedule-notification
:test-id="testId"
:schedule-receiver-options="scheduleReceiverOptions"
/>
<ms-schedule-notification :test-id="testId" :schedule-receiver-options="scheduleReceiverOptions" />
</el-tab-pane>
</el-tabs>
</div>
@ -155,17 +103,8 @@
import { saveNotice } from '@/api/notice';
import { apiScenarioEnv, createSchedule, updateSchedule } from '@/api/scenario';
import { getScheduleByIdAndType, scheduleUpdate } from '@/api/schedule';
import {
getCurrentProjectID,
getCurrentUser,
getCurrentWorkspaceId,
} from 'metersphere-frontend/src/utils/token';
import {
listenGoBack,
objToStrMap,
removeGoBackListener,
strMapToObj,
} from 'metersphere-frontend/src/utils';
import { getCurrentProjectID, getCurrentUser, getCurrentWorkspaceId } from 'metersphere-frontend/src/utils/token';
import { listenGoBack, objToStrMap, removeGoBackListener, strMapToObj } from 'metersphere-frontend/src/utils';
import Crontab from 'metersphere-frontend/src/components/cron/Crontab';
import CrontabResult from 'metersphere-frontend/src/components/cron/CrontabResult';
import { cronValidate } from 'metersphere-frontend/src/utils/cron';
@ -173,11 +112,7 @@ import MsScheduleNotification from './ScheduleNotification';
import ScheduleSwitch from '@/business/automation/schedule/ScheduleSwitch';
import { ENV_TYPE } from 'metersphere-frontend/src/utils/constants';
import EnvPopover from '@/business/automation/scenario/EnvPopover';
import {
getMaintainer,
getOwnerProjects,
getProjectConfig,
} from '@/api/project';
import { getMaintainer, getOwnerProjects, getProjectConfig } from '@/api/project';
import { getTestResourcePools } from '@/api/test-resource-pool';
import { getSystemBaseSetting } from 'metersphere-frontend/src/api/system';
import { hasLicense } from 'metersphere-frontend/src/utils/permission';
@ -252,9 +187,7 @@ export default {
paramRow: {},
activeName: 'first',
rules: {
cronValue: [
{ required: true, validator: validateCron, trigger: 'blur' },
],
cronValue: [{ required: true, validator: validateCron, trigger: 'blur' }],
},
resourcePools: [],
runConfig: {
@ -397,26 +330,24 @@ export default {
findSchedule() {
let scheduleResourceID = this.testId;
let taskType = this.scheduleTaskType;
this.result = getScheduleByIdAndType(scheduleResourceID, taskType).then(
(response) => {
if (response.data != null) {
this.schedule = response.data;
if (response.data.config) {
this.runConfig = JSON.parse(response.data.config);
if (this.runConfig.envMap) {
this.projectEnvListMap = objToStrMap(this.runConfig.envMap);
} else {
this.projectEnvListMap = new Map();
}
this.result = getScheduleByIdAndType(scheduleResourceID, taskType).then((response) => {
if (response.data != null) {
this.schedule = response.data;
if (response.data.config) {
this.runConfig = JSON.parse(response.data.config);
if (this.runConfig.envMap) {
this.projectEnvListMap = objToStrMap(this.runConfig.envMap);
} else {
this.projectEnvListMap = new Map();
}
} else {
this.schedule = {
value: '',
enable: false,
};
}
} else {
this.schedule = {
value: '',
enable: false,
};
}
);
});
},
crontabFill(value, resultList) {
//
@ -466,27 +397,14 @@ export default {
}
if (this.schedule.enable) {
if (
(this.runConfig.environmentType === 'JSON' &&
Object.keys(this.runConfig.envMap).length === 0) ||
(this.runConfig.environmentType === 'GROUP' &&
!this.runConfig.environmentGroupId)
(this.runConfig.environmentType === 'JSON' && Object.keys(this.runConfig.envMap).length === 0) ||
(this.runConfig.environmentType === 'GROUP' && !this.runConfig.environmentGroupId)
) {
this.$warning(
this.$t(
'workspace.env_group.please_select_env_for_current_scenario'
)
);
this.$warning(this.$t('workspace.env_group.please_select_env_for_current_scenario'));
return;
}
if (
this.runConfig.runWithinResourcePool &&
this.runConfig.resourcePoolId == null
) {
this.$warning(
this.$t(
'workspace.env_group.please_select_run_within_resource_pool'
)
);
if (this.runConfig.runWithinResourcePool && this.runConfig.resourcePoolId == null) {
this.$warning(this.$t('workspace.env_group.please_select_run_within_resource_pool'));
return;
}
}
@ -571,8 +489,7 @@ export default {
.head {
border-bottom: 1px solid var(--primary_color);
color: var(--primary_color);
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
font-size: 13px;
cursor: pointer;
}

View File

@ -2,12 +2,7 @@
<div>
<el-row>
<el-col :span="10">
<el-button
icon="el-icon-circle-plus-outline"
plain
size="mini"
@click="handleAddTaskModel"
>
<el-button icon="el-icon-circle-plus-outline" plain size="mini" @click="handleAddTaskModel">
{{ $t('organization.message.create_new_notification') }}
</el-button>
</el-col>
@ -21,8 +16,7 @@
:receive-type-options="receiveTypeOptions"
@handleReceivers="handleReceivers"
@handleTemplate="handleTemplate"
@refresh="initForm"
/>
@refresh="initForm" />
</el-col>
</el-row>
<mx-notice-template v-xpack ref="noticeTemplate" :variables="variables" />
@ -42,8 +36,7 @@ export default {
NotificationTable,
MsTipButton,
MsCodeEdit,
MxNoticeTemplate: () =>
import('metersphere-frontend/src/components/MxNoticeTemplate'),
MxNoticeTemplate: () => import('metersphere-frontend/src/components/MxNoticeTemplate'),
},
props: {
testId: String,
@ -264,9 +257,7 @@ export default {
}
},
handleReceivers(row) {
row.receiverOptions = JSON.parse(
JSON.stringify(this.scheduleReceiverOptions)
);
row.receiverOptions = JSON.parse(JSON.stringify(this.scheduleReceiverOptions));
},
},
};

View File

@ -5,26 +5,15 @@
<i class="el-icon-date" size="small"></i>
<span class="character">SCHEDULER</span>
</span>
<el-switch
:disabled="!schedule.value"
v-model="schedule.enable"
@change="scheduleChange"
/>
<el-switch :disabled="!schedule.value" v-model="schedule.enable" @change="scheduleChange" />
</div>
<div>
<span>
{{ $t('schedule.next_execution_time') }}
<span
:class="{ 'disable-character': !schedule.enable }"
v-if="!schedule.enable"
>{{ $t('schedule.not_set') }}</span
>
<crontab-result
v-if="schedule.enable"
:enable-simple-mode="true"
:ex="cornValue"
ref="crontabResult"
/>
<span :class="{ 'disable-character': !schedule.enable }" v-if="!schedule.enable">{{
$t('schedule.not_set')
}}</span>
<crontab-result v-if="schedule.enable" :enable-simple-mode="true" :ex="cornValue" ref="crontabResult" />
</span>
</div>
</div>

View File

@ -7,8 +7,7 @@
:current-scenario="oldData"
:node="oldNode"
:env-map="oldProjectEnvMap"
:show-version="false"
/>
:show-version="false" />
</el-card>
<el-card ref="new" style="width: 50%">
<ms-component-config
@ -17,8 +16,7 @@
:current-scenario="newData"
:node="newNode"
:env-map="newProjectEnvMap"
:show-version="false"
/>
:show-version="false" />
</el-card>
</div>
</template>

View File

@ -4,16 +4,12 @@
<el-col :span="12">
<el-tag>当前{{ oldData.versionName }}</el-tag>
<span style="margin-left: 10px">{{ oldUserName }}</span
><span style="margin-left: 10px">{{
oldCreateTime | datetimeFormat
}}</span>
><span style="margin-left: 10px">{{ oldCreateTime | datetimeFormat }}</span>
</el-col>
<el-col :span="12">
<el-tag>{{ newData.versionName }}</el-tag>
<span style="margin-left: 10px">{{ newData.userName }}</span
><span style="margin-left: 10px">{{
newCreateTime | datetimeFormat
}}</span>
><span style="margin-left: 10px">{{ newCreateTime | datetimeFormat }}</span>
</el-col>
</el-row>
<div class="compare-class" v-loading="isReloadData">
@ -30,126 +26,79 @@
:rules="rules"
:disabled="true"
ref="currentScenario"
style="margin-right: 20px"
>
style="margin-right: 20px">
<!-- 基础信息 -->
<el-row>
<el-col :span="7">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input
class="ms-scenario-input"
size="small"
v-model="oldData.name"
/>
<el-input class="ms-scenario-input" size="small" v-model="oldData.name" />
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
:label="$t('test_track.module.module')"
prop="apiScenarioModuleId"
>
<el-form-item :label="$t('test_track.module.module')" prop="apiScenarioModuleId">
<ms-select-tree
size="small"
:data="moduleOptions"
:defaultKey="oldData.apiScenarioModuleId"
:obj="moduleObj"
clearable
checkStrictly
/>
checkStrictly />
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item :label="$t('commons.status')" prop="status">
<el-select
class="ms-scenario-input"
size="small"
v-model="oldData.status"
>
<el-option
v-for="item in options"
:key="item.id"
:label="$t(item.label)"
:value="item.id"
/>
<el-select class="ms-scenario-input" size="small" v-model="oldData.status">
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="7">
<el-form-item
:label="$t('api_test.definition.request.responsible')"
prop="principal"
>
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="principal">
<el-select
v-model="oldData.principal"
:placeholder="
$t('api_test.definition.request.responsible')
"
:placeholder="$t('api_test.definition.request.responsible')"
filterable
size="small"
class="ms-scenario-input"
>
class="ms-scenario-input">
<el-option
v-for="item in maintainerOptions"
:key="item.id"
:label="item.name + ' (' + item.id + ')'"
:value="item.id"
>
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
:label="$t('test_track.case.priority')"
prop="level"
>
<el-select
class="ms-scenario-input"
size="small"
v-model="oldData.level"
>
<el-option
v-for="item in levels"
:key="item.id"
:label="item.label"
:value="item.id"
/>
<el-form-item :label="$t('test_track.case.priority')" prop="level">
<el-select class="ms-scenario-input" size="small" v-model="oldData.level">
<el-option v-for="item in levels" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
:label="$t('api_test.automation.tag')"
prop="tags"
>
<el-form-item :label="$t('api_test.automation.tag')" prop="tags">
<ms-input-tag :currentScenario="oldData" ref="tag" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="7">
<el-form-item
:label="$t('commons.description')"
prop="description"
>
<el-form-item :label="$t('commons.description')" prop="description">
<el-input
class="ms-http-textarea"
v-model="oldData.description"
type="textarea"
:autosize="{ minRows: 1, maxRows: 10 }"
:rows="1"
size="small"
/>
size="small" />
</el-form-item>
</el-col>
<el-col :span="7" v-if="customNum">
<el-form-item label="ID" prop="customNum">
<el-input
v-model.trim="oldData.customNum"
size="small"
></el-input>
<el-input v-model.trim="oldData.customNum" size="small"></el-input>
</el-form-item>
</el-col>
</el-row>
@ -163,56 +112,35 @@
<el-row>
<el-col :span="21">
<!-- 调试部分 -->
<div
class="ms-debug-div"
@click="showAll"
:class="{ 'is-top': isTop }"
ref="debugHeader"
>
<div class="ms-debug-div" @click="showAll" :class="{ 'is-top': isTop }" ref="debugHeader">
<el-row style="margin: 5px">
<el-col :span="4" class="ms-col-one ms-font">
<el-tooltip placement="top" effect="light">
<template v-slot:content>
<div>
{{
oldData.name === undefined || ''
? $t('api_test.scenario.name')
: oldData.name
}}
{{ oldData.name === undefined || '' ? $t('api_test.scenario.name') : oldData.name }}
</div>
</template>
<span class="scenario-name">
{{
oldData.name === undefined || ''
? $t('api_test.scenario.name')
: oldData.name
}}
{{ oldData.name === undefined || '' ? $t('api_test.scenario.name') : oldData.name }}
</span>
</el-tooltip>
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
{{ $t('api_test.automation.step_total') }}{{
oldScenarioDefinition.length
}}
{{ $t('api_test.automation.step_total') }}{{ oldScenarioDefinition.length }}
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-link class="head"
>{{ $t('api_test.automation.scenario_total') }}
</el-link>
<el-link class="head">{{ $t('api_test.automation.scenario_total') }} </el-link>
{{ getOldVariableSize() }}
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-checkbox v-model="oldEnableCookieShare"
><span style="font-size: 13px">{{
$t('api_test.scenario.share_cookie')
}}</span></el-checkbox
><span style="font-size: 13px">{{ $t('api_test.scenario.share_cookie') }}</span></el-checkbox
>
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-checkbox v-model="oldOnSampleError"
><span style="font-size: 13px">{{
$t('commons.failure_continues')
}}</span></el-checkbox
><span style="font-size: 13px">{{ $t('commons.failure_continues') }}</span></el-checkbox
>
</el-col>
</el-row>
@ -220,26 +148,13 @@
<!-- 场景步骤内容 -->
<div ref="stepInfo" id="stepInfo">
<el-tooltip
:content="$t('api_test.automation.open_expansion')"
placement="top"
effect="light"
>
<el-tooltip :content="$t('api_test.automation.open_expansion')" placement="top" effect="light">
<i
class="el-icon-circle-plus-outline ms-open-btn ms-open-btn-left"
@click="openExpansion('old')"
/>
@click="openExpansion('old')" />
</el-tooltip>
<el-tooltip
:content="$t('api_test.automation.close_expansion')"
placement="top"
effect="light"
>
<i
class="el-icon-remove-outline ms-open-btn"
size="mini"
@click="closeExpansion('old')"
/>
<el-tooltip :content="$t('api_test.automation.close_expansion')" placement="top" effect="light">
<i class="el-icon-remove-outline ms-open-btn" size="mini" @click="closeExpansion('old')" />
</el-tooltip>
<el-tree
node-key="resourceId"
@ -249,21 +164,12 @@
:default-expanded-keys="oldExpandedNode"
:expand-on-click-node="false"
highlight-current
@node-expand="
nodeExpand(oldScenarioDefinition, null, 'old')
"
@node-collapse="
nodeCollapse(oldScenarioDefinition, null, 'old')
"
@node-expand="nodeExpand(oldScenarioDefinition, null, 'old')"
@node-collapse="nodeCollapse(oldScenarioDefinition, null, 'old')"
@node-click="oldNodeClick"
draggable
ref="stepTree"
>
<span
class="custom-tree-node father"
slot-scope="{ node, data }"
style="width: 96%"
>
ref="stepTree">
<span class="custom-tree-node father" slot-scope="{ node, data }" style="width: 96%">
<!-- 步骤组件-->
<ms-component-config
:type="data.type"
@ -272,19 +178,14 @@
:node="node"
:env-map="projectEnvMap"
:project-list="projectList"
:show-version="false"
/>
:show-version="false" />
</span>
</el-tree>
</div>
</el-col>
</el-row>
</div>
<el-backtop
target=".card-content"
:visibility-height="100"
:right="50"
></el-backtop>
<el-backtop target=".card-content" :visibility-height="100" :right="50"></el-backtop>
</div>
</el-card>
</el-card>
@ -301,126 +202,79 @@
:rules="rules"
:disabled="true"
ref="currentScenario"
style="margin-right: 20px"
>
style="margin-right: 20px">
<!-- 基础信息 -->
<el-row>
<el-col :span="7">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input
class="ms-scenario-input"
size="small"
v-model="newData.name"
/>
<el-input class="ms-scenario-input" size="small" v-model="newData.name" />
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
:label="$t('test_track.module.module')"
prop="apiScenarioModuleId"
>
<el-form-item :label="$t('test_track.module.module')" prop="apiScenarioModuleId">
<ms-select-tree
size="small"
:data="moduleOptions"
:defaultKey="newData.apiScenarioModuleId"
:obj="moduleObj"
clearable
checkStrictly
/>
checkStrictly />
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item :label="$t('commons.status')" prop="status">
<el-select
class="ms-scenario-input"
size="small"
v-model="newData.status"
>
<el-option
v-for="item in options"
:key="item.id"
:label="$t(item.label)"
:value="item.id"
/>
<el-select class="ms-scenario-input" size="small" v-model="newData.status">
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="7">
<el-form-item
:label="$t('api_test.definition.request.responsible')"
prop="principal"
>
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="principal">
<el-select
v-model="newData.principal"
:placeholder="
$t('api_test.definition.request.responsible')
"
:placeholder="$t('api_test.definition.request.responsible')"
filterable
size="small"
class="ms-scenario-input"
>
class="ms-scenario-input">
<el-option
v-for="item in maintainerOptions"
:key="item.id"
:label="item.name + ' (' + item.id + ')'"
:value="item.id"
>
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
:label="$t('test_track.case.priority')"
prop="level"
>
<el-select
class="ms-scenario-input"
size="small"
v-model="newData.level"
>
<el-option
v-for="item in levels"
:key="item.id"
:label="item.label"
:value="item.id"
/>
<el-form-item :label="$t('test_track.case.priority')" prop="level">
<el-select class="ms-scenario-input" size="small" v-model="newData.level">
<el-option v-for="item in levels" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
:label="$t('api_test.automation.tag')"
prop="tags"
>
<el-form-item :label="$t('api_test.automation.tag')" prop="tags">
<ms-input-tag :currentScenario="newData" ref="tag" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="7">
<el-form-item
:label="$t('commons.description')"
prop="description"
>
<el-form-item :label="$t('commons.description')" prop="description">
<el-input
class="ms-http-textarea"
v-model="newData.description"
type="textarea"
:autosize="{ minRows: 1, maxRows: 10 }"
:rows="1"
size="small"
/>
size="small" />
</el-form-item>
</el-col>
<el-col :span="7" v-if="customNum">
<el-form-item label="ID" prop="customNum">
<el-input
v-model.trim="newData.customNum"
size="small"
></el-input>
<el-input v-model.trim="newData.customNum" size="small"></el-input>
</el-form-item>
</el-col>
</el-row>
@ -434,56 +288,35 @@
<el-row>
<el-col :span="21">
<!-- 调试部分 -->
<div
class="ms-debug-div"
@click="showAll"
:class="{ 'is-top': isTop }"
ref="debugHeader"
>
<div class="ms-debug-div" @click="showAll" :class="{ 'is-top': isTop }" ref="debugHeader">
<el-row style="margin: 5px">
<el-col :span="4" class="ms-col-one ms-font">
<el-tooltip placement="top" effect="light">
<template v-slot:content>
<div>
{{
newData.name === undefined || ''
? $t('api_test.scenario.name')
: newData.name
}}
{{ newData.name === undefined || '' ? $t('api_test.scenario.name') : newData.name }}
</div>
</template>
<span class="scenario-name">
{{
newData.name === undefined || ''
? $t('api_test.scenario.name')
: newData.name
}}
{{ newData.name === undefined || '' ? $t('api_test.scenario.name') : newData.name }}
</span>
</el-tooltip>
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
{{ $t('api_test.automation.step_total') }}{{
newScenarioDefinition.length
}}
{{ $t('api_test.automation.step_total') }}{{ newScenarioDefinition.length }}
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-link class="head"
>{{ $t('api_test.automation.scenario_total') }}
</el-link>
<el-link class="head">{{ $t('api_test.automation.scenario_total') }} </el-link>
{{ getNewVariableSize() }}
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-checkbox v-model="newEnableCookieShare"
><span style="font-size: 13px">{{
$t('api_test.scenario.share_cookie')
}}</span></el-checkbox
><span style="font-size: 13px">{{ $t('api_test.scenario.share_cookie') }}</span></el-checkbox
>
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-checkbox v-model="newOnSampleError"
><span style="font-size: 13px">{{
$t('commons.failure_continues')
}}</span></el-checkbox
><span style="font-size: 13px">{{ $t('commons.failure_continues') }}</span></el-checkbox
>
</el-col>
</el-row>
@ -491,26 +324,13 @@
<!-- 场景步骤内容 -->
<div ref="newStepInfo">
<el-tooltip
:content="$t('api_test.automation.open_expansion')"
placement="top"
effect="light"
>
<el-tooltip :content="$t('api_test.automation.open_expansion')" placement="top" effect="light">
<i
class="el-icon-circle-plus-outline ms-open-btn ms-open-btn-left"
@click="openExpansion('new')"
/>
@click="openExpansion('new')" />
</el-tooltip>
<el-tooltip
:content="$t('api_test.automation.close_expansion')"
placement="top"
effect="light"
>
<i
class="el-icon-remove-outline ms-open-btn"
size="mini"
@click="closeExpansion('new')"
/>
<el-tooltip :content="$t('api_test.automation.close_expansion')" placement="top" effect="light">
<i class="el-icon-remove-outline ms-open-btn" size="mini" @click="closeExpansion('new')" />
</el-tooltip>
<el-tree
node-key="resourceId"
@ -520,21 +340,12 @@
:expand-on-click-node="false"
:default-expanded-keys="newExpandedNode"
highlight-current
@node-expand="
nodeExpand(newScenarioDefinition, null, 'new')
"
@node-collapse="
nodeCollapse(newScenarioDefinition, null, 'new')
"
@node-expand="nodeExpand(newScenarioDefinition, null, 'new')"
@node-collapse="nodeCollapse(newScenarioDefinition, null, 'new')"
@node-click="nodeClick"
draggable
ref="newStepTree"
>
<span
class="custom-tree-node father"
slot-scope="{ node, data }"
style="width: 96%"
>
ref="newStepTree">
<span class="custom-tree-node father" slot-scope="{ node, data }" style="width: 96%">
<!-- 步骤组件-->
<ms-component-config
:type="data.type"
@ -543,8 +354,7 @@
:node="node"
:env-map="newProjectEnvMap"
:project-list="projectList"
:show-version="false"
/>
:show-version="false" />
</span>
</el-tree>
</div>
@ -552,21 +362,11 @@
</el-row>
</div>
<el-backtop
target=".card-content"
:visibility-height="100"
:right="50"
></el-backtop>
<el-backtop target=".card-content" :visibility-height="100" :right="50"></el-backtop>
</div>
</el-card>
</el-card>
<el-dialog
:fullscreen="true"
:visible.sync="dialogVisible"
:destroy-on-close="true"
append-to-body
width="100%"
>
<el-dialog :fullscreen="true" :visible.sync="dialogVisible" :destroy-on-close="true" append-to-body width="100%">
<scenario-child-diff
v-if="dialogVisible"
:old-data="leftChildData"
@ -578,8 +378,7 @@
:old-v-node="leftChildVnode"
:new-v-node="rightChildVnode"
:old-color="oldColor"
:new-color="newColor"
></scenario-child-diff>
:new-color="newColor"></scenario-child-diff>
</el-dialog>
</div>
</div>
@ -640,8 +439,7 @@ export default {
components: {
ScenarioChildDiff,
MsComponentConfig,
MsSelectTree: () =>
import('metersphere-frontend/src/components/select-tree/SelectTree'),
MsSelectTree: () => import('metersphere-frontend/src/components/select-tree/SelectTree'),
MsInputTag: () => import('@/business/automation/scenario/MsInputTag'),
EnvPopover: () => import('@/business/automation/scenario/EnvPopover'),
},
@ -708,89 +506,76 @@ export default {
methods: {
getCurrentScenario() {
if (this.currentScenarioId) {
this.result = getScenarioWithBLOBsById(this.currentScenarioId).then(
(response) => {
if (response.data) {
if (response.data.scenarioDefinition != null) {
let obj = JSON.parse(response.data.scenarioDefinition);
if (obj) {
this.oldScenarioDefinition = obj.hashTree;
this.result = getScenarioWithBLOBsById(this.currentScenarioId).then((response) => {
if (response.data) {
if (response.data.scenarioDefinition != null) {
let obj = JSON.parse(response.data.scenarioDefinition);
if (obj) {
this.oldScenarioDefinition = obj.hashTree;
}
}
this.oldData = response.data;
getFollowByScenarioId(this.currentScenarioId).then((response) => {
this.oldData.follows = response.data;
for (let i = 0; i < response.data.length; i++) {
if (response.data[i] === this.currentUser().id) {
this.showFollow = true;
break;
}
}
this.oldData = response.data;
getFollowByScenarioId(this.currentScenarioId).then((response) => {
this.oldData.follows = response.data;
for (let i = 0; i < response.data.length; i++) {
if (response.data[i] === this.currentUser().id) {
this.showFollow = true;
break;
}
}
});
}
});
}
);
});
}
},
getDffScenario() {
getScenarioById(this.dffScenarioId + '/' + this.scenarioRefId).then(
(response) => {
getScenarioWithBLOBsById(response.data.id).then((res) => {
if (res.data) {
if (res.data.scenarioDefinition != null) {
let obj = JSON.parse(res.data.scenarioDefinition);
if (obj) {
if (obj.hashTree) {
for (let i = 0; i < obj.hashTree.length; i++) {
if (!obj.hashTree[i].index) {
obj.hashTree[i].index = i + 1;
}
obj.hashTree[i].disabled = true;
if (!obj.hashTree[i].requestResult) {
obj.hashTree[i].requestResult = [
{ responseResult: {} },
];
}
getScenarioById(this.dffScenarioId + '/' + this.scenarioRefId).then((response) => {
getScenarioWithBLOBsById(response.data.id).then((res) => {
if (res.data) {
if (res.data.scenarioDefinition != null) {
let obj = JSON.parse(res.data.scenarioDefinition);
if (obj) {
if (obj.hashTree) {
for (let i = 0; i < obj.hashTree.length; i++) {
if (!obj.hashTree[i].index) {
obj.hashTree[i].index = i + 1;
}
this.newEnableCookieShare = obj.enableCookieShare;
if (obj.onSampleError === undefined) {
this.newOnSampleError = true;
} else {
this.newOnSampleError = obj.onSampleError;
obj.hashTree[i].disabled = true;
if (!obj.hashTree[i].requestResult) {
obj.hashTree[i].requestResult = [{ responseResult: {} }];
}
}
this.newScenarioDefinition = obj.hashTree;
for (let i = 0; i < this.oldScenarioDefinition.length; i++) {
this.oldScenarioDefinition[i].disabled = true;
}
if (response.data.environmentJson) {
this.newProjectEnvMap = objToStrMap(
JSON.parse(response.data.environmentJson)
);
this.newEnableCookieShare = obj.enableCookieShare;
if (obj.onSampleError === undefined) {
this.newOnSampleError = true;
} else {
//
this.newProjectEnvMap.set(
this.projectId,
obj.environmentId
);
this.newOnSampleError = obj.onSampleError;
}
}
this.newScenarioDefinition = obj.hashTree;
for (let i = 0; i < this.oldScenarioDefinition.length; i++) {
this.oldScenarioDefinition[i].disabled = true;
}
if (response.data.environmentJson) {
this.newProjectEnvMap = objToStrMap(JSON.parse(response.data.environmentJson));
} else {
//
this.newProjectEnvMap.set(this.projectId, obj.environmentId);
}
}
res.data.userName = response.data.userName;
this.dealWithTag(res.data);
this.newData = res.data;
this.closeExpansion();
this.showDiff = true;
}
});
}
);
res.data.userName = response.data.userName;
this.dealWithTag(res.data);
this.newData = res.data;
this.closeExpansion();
this.showDiff = true;
}
});
});
},
dealWithTag(newScenario) {
if (newScenario.tags) {
if (
Object.prototype.toString.call(newScenario.tags) === '[object String]'
) {
if (Object.prototype.toString.call(newScenario.tags) === '[object String]') {
newScenario.tags = JSON.parse(newScenario.tags);
}
}
@ -914,19 +699,11 @@ export default {
},
nodeExpand(data, node, source) {
if (source === 'new') {
if (
data &&
data.resourceId &&
this.newExpandedNode.indexOf(data.resourceId) === -1
) {
if (data && data.resourceId && this.newExpandedNode.indexOf(data.resourceId) === -1) {
this.newExpandedNode.push(data.resourceId);
}
} else {
if (
data &&
data.resourceId &&
this.oldExpandedNode.indexOf(data.resourceId) === -1
) {
if (data && data.resourceId && this.oldExpandedNode.indexOf(data.resourceId) === -1) {
this.oldExpandedNode.push(data.resourceId);
}
}
@ -934,15 +711,9 @@ export default {
nodeCollapse(data, node, source) {
if (data && data.resourceId) {
if (source === 'new') {
this.newExpandedNode.splice(
this.newExpandedNode.indexOf(data.resourceId),
1
);
this.newExpandedNode.splice(this.newExpandedNode.indexOf(data.resourceId), 1);
} else {
this.oldExpandedNode.splice(
this.oldExpandedNode.indexOf(data.resourceId),
1
);
this.oldExpandedNode.splice(this.oldExpandedNode.indexOf(data.resourceId), 1);
}
}
},

View File

@ -65,29 +65,15 @@ export function diff(oldDom, newDom, oldColor, newColor) {
function changeStyle(diffNode, oldColor, newColor) {
for (let i = 0; i < diffNode.oldNodeArray.length; i++) {
if (
diffNode.oldNodeArray[i] === 'comment' ||
diffNode.oldNodeArray[i].nodeName === '#comment'
) {
if (diffNode.oldNodeArray[i] === 'comment' || diffNode.oldNodeArray[i].nodeName === '#comment') {
continue;
}
if (diffNode.oldNodeArray[i].className === 'cell') {
let rowVnodeElm = findRowVnodeElm(diffNode.oldNodeArray[i]);
if (isDef(rowVnodeElm.style)) {
rowVnodeElm.style.setProperty(
'background-color',
oldColor,
'important'
);
} else if (
isDef(rowVnodeElm.parentNode.style) &&
rowVnodeElm !== 'comment'
) {
rowVnodeElm.parentNode.style.setProperty(
'background-color',
oldColor,
'important'
);
rowVnodeElm.style.setProperty('background-color', oldColor, 'important');
} else if (isDef(rowVnodeElm.parentNode.style) && rowVnodeElm !== 'comment') {
rowVnodeElm.parentNode.style.setProperty('background-color', oldColor, 'important');
}
} else {
changeStyleBySubset(diffNode.oldNodeArray[i], oldColor);
@ -95,29 +81,15 @@ function changeStyle(diffNode, oldColor, newColor) {
}
for (let i = 0; i < diffNode.nodeArray.length; i++) {
if (
diffNode.nodeArray[i] === 'comment' ||
diffNode.nodeArray[i].nodeName === '#comment'
) {
if (diffNode.nodeArray[i] === 'comment' || diffNode.nodeArray[i].nodeName === '#comment') {
continue;
}
if (diffNode.nodeArray[i].className === 'cell') {
let rowVnodeElm = findRowVnodeElm(diffNode.nodeArray[i]);
if (isDef(rowVnodeElm.style)) {
rowVnodeElm.style.setProperty(
'background-color',
newColor,
'important'
);
} else if (
isDef(rowVnodeElm.parentNode.style) &&
rowVnodeElm !== 'comment'
) {
rowVnodeElm.parentNode.style.setProperty(
'background-color',
newColor,
'important'
);
rowVnodeElm.style.setProperty('background-color', newColor, 'important');
} else if (isDef(rowVnodeElm.parentNode.style) && rowVnodeElm !== 'comment') {
rowVnodeElm.parentNode.style.setProperty('background-color', newColor, 'important');
}
} else {
changeStyleBySubset(diffNode.nodeArray[i], newColor);
@ -131,11 +103,7 @@ function changeStyleBySubset(vnodeElm, color) {
if (isDef(vnodeElm.style)) {
vnodeElm.style.setProperty('background-color', color, 'important');
} else if (isDef(vnodeElm.parentNode.style) && vnodeElm !== 'comment') {
vnodeElm.parentNode.style.setProperty(
'background-color',
color,
'important'
);
vnodeElm.parentNode.style.setProperty('background-color', color, 'important');
}
for (let i = 0; i < vnodeElm.children.length; i++) {
changeStyleBySubset(vnodeElm.children[i], color);
@ -144,11 +112,7 @@ function changeStyleBySubset(vnodeElm, color) {
if (isDef(vnodeElm.style)) {
vnodeElm.style.setProperty('background-color', color, 'important');
} else if (isDef(vnodeElm.parentNode.style) && vnodeElm !== 'comment') {
vnodeElm.parentNode.style.setProperty(
'background-color',
color,
'important'
);
vnodeElm.parentNode.style.setProperty('background-color', color, 'important');
}
}
}
@ -241,12 +205,7 @@ function sameDetail(oldVnode, newVnode, sameNode) {
sameChildren(oldVnode.children, newVnode.children, sameNode);
}
//剩最后的子节点的时候分类型做判断如果最后的子节点有一个不相同sameNode就置空
if (
isUndef(oldVnode.child) &&
isUndef(newVnode.child) &&
isUndef(oldVnode.children) &&
isUndef(newVnode.children)
) {
if (isUndef(oldVnode.child) && isUndef(newVnode.child) && isUndef(oldVnode.children) && isUndef(newVnode.children)) {
if (isDef(oldVnode.text) && isDef(newVnode.text)) {
if (oldVnode.text === newVnode.text) {
sameNode.nodeArray.push(newVnode.elm);
@ -256,10 +215,7 @@ function sameDetail(oldVnode, newVnode, sameNode) {
} else if (isDef(oldVnode.tag) && isDef(newVnode.tag)) {
if (oldVnode.tag === 'input' && newVnode.tag === 'input') {
if (oldVnode.elm.value === newVnode.elm.value) {
if (
oldVnode.elm.checked !== undefined &&
newVnode.elm.checked !== undefined
) {
if (oldVnode.elm.checked !== undefined && newVnode.elm.checked !== undefined) {
if (oldVnode.elm.checked === newVnode.elm.checked) {
sameNode.nodeArray.push(newVnode.elm);
} else {
@ -314,27 +270,14 @@ function diffDetail(oldVnode, newVnode, diffNode) {
if (oldVnode.tag === 'tbody' && newVnode.tag === 'tbody') {
isCompareChildren = true;
} else if (isDef(oldVnode.elm.className) && isDef(newVnode.elm.className)) {
if (
oldVnode.elm.className === 'el-collapse' &&
newVnode.elm.className === 'el-collapse'
) {
if (oldVnode.elm.className === 'el-collapse' && newVnode.elm.className === 'el-collapse') {
isCompareChildren = true;
}
}
diffChildren(
oldVnode.children,
newVnode.children,
diffNode,
isCompareChildren
);
diffChildren(oldVnode.children, newVnode.children, diffNode, isCompareChildren);
}
//剩最后的子节点的时候,分类型做判断(注意最后的子节点的真实dom里可能还有dom节点)
if (
isUndef(oldVnode.child) &&
isUndef(newVnode.child) &&
isUndef(oldVnode.children) &&
isUndef(newVnode.children)
) {
if (isUndef(oldVnode.child) && isUndef(newVnode.child) && isUndef(oldVnode.children) && isUndef(newVnode.children)) {
//最子节点比较结果
let childDiff = [];
diffRealNode(oldVnode.elm, newVnode.elm, diffNode, childDiff);
@ -352,10 +295,7 @@ function diffDetail(oldVnode, newVnode, diffNode) {
diffNode.oldNodeArray.push(oldVnode.elm);
diffNode.nodeArray.push(newVnode.elm);
} else {
if (
oldVnode.elm.checked !== undefined &&
newVnode.elm.checked !== undefined
) {
if (oldVnode.elm.checked !== undefined && newVnode.elm.checked !== undefined) {
if (oldVnode.elm.checked !== newVnode.elm.checked) {
diffNode.oldNodeArray.push(oldVnode.elm);
diffNode.nodeArray.push(newVnode.elm);
@ -485,10 +425,7 @@ function sameVnode(a, b) {
return (
a.key === b.key &&
a.asyncFactory === b.asyncFactory &&
((a.tag === b.tag &&
a.isComment === b.isComment &&
isDef(a.data) === isDef(b.data) &&
sameInputType(a, b)) ||
((a.tag === b.tag && a.isComment === b.isComment && isDef(a.data) === isDef(b.data) && sameInputType(a, b)) ||
(isTrue(a.isAsyncPlaceholder) && isUndef(b.asyncFactory.error)))
);
}

View File

@ -7,72 +7,37 @@
class="batch-edit-dialog"
:destroy-on-close="true"
@close="handleClose"
v-loading="result"
>
<el-form
:model="form"
label-position="right"
label-width="180px"
size="medium"
ref="form"
:rules="rules"
>
<el-form-item
:label="$t('test_track.case.batch_update', [size])"
prop="type"
>
<el-select
v-model="form.type"
style="width: 100%"
@change="changeType"
>
v-loading="result">
<el-form :model="form" label-position="right" label-width="180px" size="medium" ref="form" :rules="rules">
<el-form-item :label="$t('test_track.case.batch_update', [size])" prop="type">
<el-select v-model="form.type" style="width: 100%" @change="changeType">
<el-option
v-for="(type, index) in typeArr"
:key="index"
:value="type.custom ? type.custom : type.id"
:label="type.name"
/>
:label="type.name" />
</el-select>
</el-form-item>
<el-form-item
v-if="form.type === 'projectEnv'"
:label="$t('test_track.case.updated_attr_value')"
>
<el-form-item v-if="form.type === 'projectEnv'" :label="$t('test_track.case.updated_attr_value')">
<env-popover
:env-map="projectEnvMap"
:project-ids="projectIds"
@setProjectEnvMap="setProjectEnvMap"
:show-config-button-with-out-permission="
showConfigButtonWithOutPermission
"
:show-config-button-with-out-permission="showConfigButtonWithOutPermission"
:project-list="projectList"
:environment-type.sync="environmentType"
:group-id="envGroupId"
:is-scenario="false"
@setEnvGroup="setEnvGroup"
ref="envPopover"
/>
ref="envPopover" />
</el-form-item>
<el-form-item
v-else-if="form.type === 'tags'"
:label="$t('test_track.case.updated_attr_value')"
>
<ms-input-tag
:currentScenario="form"
v-if="showInputTag"
ref="tag"
class="ms-case-input"
></ms-input-tag>
<el-form-item v-else-if="form.type === 'tags'" :label="$t('test_track.case.updated_attr_value')">
<ms-input-tag :currentScenario="form" v-if="showInputTag" ref="tag" class="ms-case-input"></ms-input-tag>
<el-checkbox v-model="form.appendTag">
{{ $t('commons.append_tag') }}
<el-tooltip
class="item"
effect="dark"
:content="$t('commons.append_tag_tip')"
placement="top"
>
<el-tooltip class="item" effect="dark" :content="$t('commons.append_tag_tip')" placement="top">
<i class="el-icon-info"></i>
</el-tooltip>
</el-checkbox>
@ -81,27 +46,13 @@
<el-form-item
v-else-if="fieldType === 'custom'"
prop="customFieldValue"
:label="$t('test_track.case.updated_attr_value')"
>
:label="$t('test_track.case.updated_attr_value')">
<custom-filed-component :data="customField" prop="defaultValue" />
</el-form-item>
<el-form-item
v-else
:label="$t('test_track.case.updated_attr_value')"
prop="value"
>
<el-select
v-model="form.value"
style="width: 100%"
:filterable="filterable"
>
<el-option
v-for="(option, index) in options"
:key="index"
:value="option.id"
:label="option.name"
>
<el-form-item v-else :label="$t('test_track.case.updated_attr_value')" prop="value">
<el-select v-model="form.value" style="width: 100%" :filterable="filterable">
<el-option v-for="(option, index) in options" :key="index" :value="option.id" :label="option.name">
<div v-if="option.email">
<span>{{ option.id }}({{ option.name }})</span>
</div>
@ -110,10 +61,7 @@
</el-form-item>
</el-form>
<template v-slot:footer>
<ms-dialog-footer
@cancel="dialogVisible = false"
@confirm="submit('form')"
/>
<ms-dialog-footer @cancel="dialogVisible = false" @confirm="submit('form')" />
</template>
</el-dialog>
</div>
@ -121,10 +69,7 @@
<script>
import MsDialogFooter from 'metersphere-frontend/src/components/MsDialogFooter';
import {
listenGoBack,
removeGoBackListener,
} from 'metersphere-frontend/src/utils';
import { listenGoBack, removeGoBackListener } from 'metersphere-frontend/src/utils';
import EnvPopover from '@/business/automation/scenario/EnvPopover';
import { ENV_TYPE } from 'metersphere-frontend/src/utils/constants';
import CustomFiledComponent from 'metersphere-frontend/src/components/template/CustomFiledComponent';

Some files were not shown because too many files have changed in this diff Show More