feat(接口测试): mock接口联调完成

This commit is contained in:
baiqi 2024-05-11 14:36:09 +08:00 committed by 刘瑞斌
parent 9315555a09
commit 26b054f96f
11 changed files with 401 additions and 278 deletions

View File

@ -28,7 +28,7 @@
</a-tooltip>
</div>
</div>
<div v-if="showBody" class="ms-assertion-body w-full">
<div v-if="showBody" class="ms-assertion-body w-full overflow-hidden">
<div class="ms-assertion-body-left h-full w-[25%] min-w-[220px]">
<VueDraggable v-model="assertions" ghost-class="ghost" handle=".sort-handle">
<div
@ -77,63 +77,61 @@
</VueDraggable>
</div>
<div
class="ms-assertion-body-right h-full"
class="ms-assertion-body-right h-full flex-1 overflow-hidden"
:class="{
'p-4 pr-0': getCurrentItemState.assertionType !== ResponseAssertionType.SCRIPT,
'border border-solid border-[var(--color-text-n8)]':
getCurrentItemState.assertionType !== ResponseAssertionType.SCRIPT,
}"
>
<div class="w-full">
<!-- 响应头 -->
<ResponseHeaderTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_HEADER"
v-model:data="getCurrentItemState"
class="pr-4"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 状态码 -->
<StatusCodeTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_CODE"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 响应体 -->
<ResponseBodyTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_BODY"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
:response="props.response"
:show-extraction="props.showExtraction"
@change="handleChange"
/>
<!-- 响应时间 -->
<ResponseTimeTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_TIME"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 变量 -->
<VariableTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.VARIABLE"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 脚本 -->
<ScriptTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.SCRIPT"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
:script-code-editor-height="props.scriptCodeEditorHeight"
@change="handleChange"
@delete-script-item="deleteScriptItem"
@copy="copyItem"
/>
</div>
<!-- 响应头 -->
<ResponseHeaderTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_HEADER"
v-model:data="getCurrentItemState"
class="pr-4"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 状态码 -->
<StatusCodeTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_CODE"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 响应体 -->
<ResponseBodyTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_BODY"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
:response="props.response"
:show-extraction="props.showExtraction"
@change="handleChange"
/>
<!-- 响应时间 -->
<ResponseTimeTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_TIME"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 变量 -->
<VariableTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.VARIABLE"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
@change="handleChange"
/>
<!-- 脚本 -->
<ScriptTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.SCRIPT"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
:script-code-editor-height="props.scriptCodeEditorHeight"
@change="handleChange"
@delete-script-item="deleteScriptItem"
@copy="copyItem"
/>
</div>
</div>
</div>

View File

@ -893,6 +893,7 @@
...file,
fileId: res.data,
fileName: file.name || '',
fileAlias: file.name || '',
};
break;
}
@ -902,7 +903,8 @@
record.files = files.map((e) => ({
...e,
fileId: e.uid || e.fileId || '',
fileName: e.name || e.fileName || '',
fileName: e.originalName || '',
fileAlias: e.name || '',
}));
}
addTableLine(rowIndex);

View File

@ -376,7 +376,10 @@
(e: 'openCopyApiTab', record: ApiDefinitionDetail): void;
(e: 'addApiTab'): void;
(e: 'import'): void;
(e: 'openEditApiTab', record: ApiDefinitionDetail, isCopy: boolean, isExecute: boolean, isEdit: boolean): void;
(
e: 'openEditApiTab',
options: { apiInfo: ApiDefinitionDetail; isCopy: boolean; isExecute: boolean; isEdit: boolean }
): void;
}>();
const appStore = useAppStore();
@ -977,7 +980,7 @@
}
function editDefinition(record: ApiDefinitionDetail) {
emit('openEditApiTab', record, false, false, true);
emit('openEditApiTab', { apiInfo: record, isCopy: false, isExecute: false, isEdit: true });
}
//

View File

@ -7,8 +7,8 @@
:protocol="props.protocol"
:refresh-time-stamp="refreshTableTimeStamp"
:member-options="memberOptions"
@open-api-tab="(record, isExecute) => openApiTab(record, false, isExecute)"
@open-copy-api-tab="openApiTab($event, true)"
@open-api-tab="(record, isExecute) => openApiTab({ apiInfo: record, isCopy: false, isExecute })"
@open-copy-api-tab="openApiTab({ apiInfo: $event, isCopy: true })"
@add-api-tab="addApiTab"
@import="emit('import')"
@open-edit-api-tab="openApiTab"
@ -117,6 +117,7 @@
:definition-detail="activeApiTab"
:protocol="activeApiTab.protocol"
is-api
@debug="openApiTabAndDebugMock"
/>
</a-tab-pane>
</a-tabs>
@ -158,10 +159,18 @@
RequestComposition,
RequestDefinitionStatus,
RequestMethods,
RequestParamsType,
ResponseComposition,
} from '@/enums/apiEnum';
import { defaultBodyParams, defaultResponse, defaultResponseItem } from '@/views/api-test/components/config';
import {
defaultBodyParams,
defaultBodyParamsItem,
defaultHeaderParamsItem,
defaultRequestParamsItem,
defaultResponse,
defaultResponseItem,
} from '@/views/api-test/components/config';
import type { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
import { parseRequestBodyFiles } from '@/views/api-test/components/utils';
// requestComposition
@ -315,20 +324,29 @@
const loading = ref(false);
const requestCompositionRef = ref<InstanceType<typeof requestComposition>>();
async function openApiTab(
apiInfo: ModuleTreeNode | ApiDefinitionDetail | string,
isCopy = false,
isExecute = false,
isEdit = false
) {
async function openApiTab(options: {
apiInfo: ModuleTreeNode | ApiDefinitionDetail | string;
isCopy?: boolean;
isExecute?: boolean;
isEdit?: boolean;
isDebugMock?: boolean;
}) {
const { apiInfo, isCopy = false, isExecute = false, isEdit = false, isDebugMock = false } = options;
const isLoadedTabIndex = apiTabs.value.findIndex(
(e) => e.id === (typeof apiInfo === 'string' ? apiInfo : apiInfo.id)
);
if (isLoadedTabIndex > -1 && !isCopy) {
const preActiveApiTabId = activeApiTab.value.id;
let loadedApiTab = apiTabs.value[isLoadedTabIndex] as RequestParam;
if (isDebugMock) {
loadedApiTab = {
...loadedApiTab,
...(apiInfo as ApiDefinitionDetail).request,
};
}
// tabtab
activeApiTab.value = {
...(apiTabs.value[isLoadedTabIndex] as RequestParam),
...loadedApiTab,
definitionActiveKey: isCopy || isExecute || isEdit ? 'definition' : 'preview',
isExecute,
mode: isExecute ? 'debug' : 'definition',
@ -352,10 +370,17 @@
if (res.protocol === 'HTTP') {
parseRequestBodyResult = parseRequestBodyFiles(res.request.body, res.response); // id
}
let { request } = res;
if (isDebugMock) {
request = {
...res.request,
...(apiInfo as ApiDefinitionDetail).request,
};
}
addApiTab({
label: name,
...res.request,
...res,
...request,
response: cloneDeep(defaultResponse),
responseDefinition: res.response.map((e) => ({ ...e, responseActiveTab: ResponseComposition.BODY })),
url: res.path,
@ -382,7 +407,58 @@
}
async function openApiTabAndDebugMock(mock: MockDetail) {
await openApiTab(mock.apiDefinitionId as string);
openApiTab({
apiInfo: {
id: mock.apiDefinitionId as string,
request: {
body: {
bodyType: mock.mockMatchRule.body.bodyType,
binaryBody: mock.mockMatchRule.body.binaryBody,
rawBody: mock.mockMatchRule.body.rawBody,
xmlBody: mock.mockMatchRule.body.xmlBody,
wwwFormBody: {
formValues:
mock.mockMatchRule.body.wwwFormBody.matchRules.map((e) => ({
...defaultBodyParamsItem,
key: e.key,
value: e.value,
})) || [],
},
jsonBody: mock.mockMatchRule.body.jsonBody,
formDataBody: {
formValues:
mock.mockMatchRule.body.formDataBody.matchRules.map((e) => ({
...defaultBodyParamsItem,
key: e.key,
value: e.value,
files: e.files || [],
paramType: e.files && e.files.length > 0 ? RequestParamsType.FILE : defaultBodyParamsItem.paramType,
})) || [],
},
},
headers:
mock.mockMatchRule.header.matchRules.map((e) => ({
...defaultHeaderParamsItem,
key: e.key,
value: e.value,
})) || [],
query:
mock.mockMatchRule.query.matchRules.map((e) => ({
...defaultRequestParamsItem,
key: e.key,
value: e.value,
})) || [],
rest:
mock.mockMatchRule.rest.matchRules.map((e) => ({
...defaultRequestParamsItem,
key: e.key,
value: e.value,
})) || [],
},
} as unknown as ApiDefinitionDetail,
isExecute: true,
isDebugMock: true,
});
}
//

View File

@ -135,7 +135,11 @@
function newTab(apiInfo?: ModuleTreeNode | string, isCopy?: boolean, isExecute?: boolean) {
if (apiInfo) {
apiRef.value?.openApiTab(apiInfo, isCopy, isExecute);
apiRef.value?.openApiTab({
apiInfo,
isCopy,
isExecute,
});
} else {
apiRef.value?.addApiTab();
}

View File

@ -60,20 +60,23 @@
</MsDetailCard>
<a-form ref="mockForm" :model="mockDetail" :disabled="isReadOnly">
<a-form-item
class="hidden-item"
class="hidden-item mb-[16px]"
field="name"
:rules="[{ required: true, message: t('mockManagement.nameNotNull') }]"
>
<a-input
v-model:model-value="mockDetail.name"
:placeholder="t('mockManagement.namePlaceholder')"
class="mb-[16px] w-[732px]"
class="w-[732px]"
></a-input>
</a-form-item>
<a-form-item class="hidden-item" :rules="[{ required: true, message: t('mockManagement.nameNotNull') }]">
<a-form-item
class="hidden-item mb-[16px]"
:rules="[{ required: true, message: t('mockManagement.nameNotNull') }]"
>
<MsTagsInput
v-model:model-value="mockDetail.tags"
class="mb-[16px] w-[732px]"
class="w-[732px]"
allow-clear
unique-value
retain-input-value
@ -374,20 +377,26 @@
const currentKeyOptions = computed(() => {
switch (activeTab.value) {
case RequestComposition.HEADER:
return filterKeyValParams(props.definitionDetail.headers, defaultMatchRuleItem).validParams.map((e) => ({
label: e.key,
value: e.key,
}));
return filterKeyValParams(props.definitionDetail.headers, defaultMatchRuleItem)
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
.map((e) => ({
label: e.key,
value: e.key,
}));
case RequestComposition.QUERY:
return filterKeyValParams(props.definitionDetail.query, defaultMatchRuleItem).validParams.map((e) => ({
label: e.key,
value: e.key,
}));
return filterKeyValParams(props.definitionDetail.query, defaultMatchRuleItem)
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
.map((e) => ({
label: e.key,
value: e.key,
}));
case RequestComposition.REST:
return filterKeyValParams(props.definitionDetail.rest, defaultMatchRuleItem).validParams.map((e) => ({
label: e.key,
value: e.key,
}));
return filterKeyValParams(props.definitionDetail.rest, defaultMatchRuleItem)
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
.map((e) => ({
label: e.key,
value: e.key,
}));
default:
return [];
}
@ -396,23 +405,21 @@
const currentBodyKeyOptions = computed(() => {
switch (mockDetail.value.mockMatchRule.body.bodyType) {
case RequestBodyFormat.FORM_DATA:
return filterKeyValParams(
props.definitionDetail.body.formDataBody.formValues,
defaultMatchRuleItem
).validParams.map((e) => ({
label: e.key,
value: e.key,
paramType: e.paramType,
}));
return filterKeyValParams(props.definitionDetail.body.formDataBody.formValues, defaultMatchRuleItem)
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
.map((e) => ({
label: e.key,
value: e.key,
paramType: e.paramType,
}));
case RequestBodyFormat.WWW_FORM:
return filterKeyValParams(
props.definitionDetail.body.wwwFormBody.formValues,
defaultMatchRuleItem
).validParams.map((e) => ({
label: e.key,
value: e.key,
paramType: e.paramType,
}));
return filterKeyValParams(props.definitionDetail.body.wwwFormBody.formValues, defaultMatchRuleItem)
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
.map((e) => ({
label: e.key,
value: e.key,
paramType: e.paramType,
}));
default:
return [];
}
@ -569,10 +576,10 @@
} else {
//
mockDetail.value.mockMatchRule.body.binaryBody.file = {
...fileList.value[0],
fileId: fileList.value[0]?.uid,
fileName: fileList.value[0]?.originalName || '',
fileAlias: fileList.value[0]?.name || '',
...file,
fileId: file?.uid || '',
fileName: file?.originalName || '',
fileAlias: file?.name || '',
local: false,
};
}

View File

@ -2,6 +2,7 @@
<a-form ref="formRef" :model="formModel" layout="vertical">
<a-spin :loading="loading" class="block">
<div
v-if="matchRules.length > 0"
:class="`flex ${
matchRules.length > 1 ? 'items-stretch' : 'items-center'
} gap-[16px] bg-[var(--color-text-n9)] p-[12px]`"
@ -97,6 +98,9 @@
</div>
</div>
</div>
<div v-else>
<a-empty :description="t('mockManagement.noMatchRules')"></a-empty>
</div>
</a-spin>
</a-form>
<a-modal
@ -265,6 +269,7 @@
...file,
fileId: res.data,
fileName: file.name || '',
fileAlias: file.name || '',
};
break;
}
@ -274,7 +279,8 @@
record.files = files.map((e) => ({
...e,
fileId: e.uid || e.fileId || '',
fileName: e.name || e.fileName || '',
fileName: e.originalName || '',
fileAlias: e.name || '',
}));
}
addMatchRule(rowIndex);

View File

@ -1,225 +1,251 @@
export default {
'apiTestManagement.newApi': 'Create request',
'apiTestManagement.importApi': 'Import api',
'apiTestManagement.fileImport': 'Import file',
'apiTestManagement.timeImport': 'Scheduled import',
'apiTestManagement.timeTask': 'Timed tasks',
'apiTestManagement.name': 'Task name',
'apiTestManagement.taskRunRule': 'Run rules',
'apiTestManagement.taskNextRunTime': 'Next execution time',
'apiTestManagement.newApi': 'New API',
'apiTestManagement.importApi': 'Import API',
'apiTestManagement.fileImport': 'File Import',
'apiTestManagement.timeImport': 'Time Import',
'apiTestManagement.timeTask': 'Time Task',
'apiTestManagement.name': 'Name',
'apiTestManagement.taskRunRule': 'Run Rule',
'apiTestManagement.taskNextRunTime': 'Next Run Time',
'apiTestManagement.taskOperator': 'Operator',
'apiTestManagement.taskOperationTime': 'Operating time',
'apiTestManagement.createTaskSuccess': 'Create scheduled import task successfully',
'apiTestManagement.enableTaskSuccess': 'Start scheduled import task successfully',
'apiTestManagement.disableTaskSuccess': 'Closing the scheduled import task successfully',
'apiTestManagement.addSubModule': 'Add submodule',
'apiTestManagement.allApi': 'All api',
'apiTestManagement.allCase': 'All case',
'apiTestManagement.searchTip': 'Please enter module/api name',
'apiTestManagement.moveSearchTip': 'Please enter the module name to search',
'apiTestManagement.noMatchModuleAndApi': 'No matching module/api yet',
'apiTestManagement.noMatchModule': 'No matching module yet',
'apiTestManagement.taskOperationTime': 'Operation Time',
'apiTestManagement.createTaskSuccess': 'Create Time Import Task Success',
'apiTestManagement.enableTaskSuccess': 'Enable Time Import Task Success',
'apiTestManagement.disableTaskSuccess': 'Disable Time Import Task Success',
'apiTestManagement.addSubModule': 'Add Submodule',
'apiTestManagement.allApi': 'All APIs',
'apiTestManagement.allCase': 'All Cases',
'apiTestManagement.searchTip': 'Please enter module/interface name',
'apiTestManagement.moveSearchTip': 'Please enter module name to search',
'apiTestManagement.noMatchModuleAndApi': 'No matching module/interface found',
'apiTestManagement.noMatchModule': 'No matching module found',
'apiTestManagement.execute': 'Execute',
'apiTestManagement.executeMethod': 'Execute method',
'apiTestManagement.executeMethod': 'Execute Method',
'apiTestManagement.recycle.batchRecover': 'Recover',
'apiTestManagement.recycle.recoveredSuccessfully': 'recovery was successful',
'apiTestManagement.recycle.batchCleanOut': 'Completely delete',
'apiTestManagement.recycle.completedDeleteCaseTitle': 'Confirm complete deletion {name}?',
'apiTestManagement.recycle.recoveredSuccessfully': 'Recovered Successfully',
'apiTestManagement.recycle.batchCleanOut': 'Clean Out',
'apiTestManagement.recycle.completedDeleteCaseTitle': 'Confirm to completely delete {name}?',
'apiTestManagement.recycle.cleanOutDeleteOnRecycleTip':
'After deletion, the API cannot be restored. Please operate with caution!',
'apiTestManagement.recycle.batchDeleteApiTip': 'Are you sure to completely delete the selected {count} interfaces?',
'After deletion, the API cannot be recovered. Please proceed with caution!',
'apiTestManagement.recycle.batchDeleteApiTip': 'Confirm to completely delete the selected {count} APIs?',
'apiTestManagement.share': 'Share API',
'apiTestManagement.shareModule': 'Share module',
'apiTestManagement.doc': 'Document',
'apiTestManagement.closeAll': 'Close all tabs',
'apiTestManagement.closeOther': 'Close other tabs',
'apiTestManagement.showSubdirectory': 'Show subdirectory use case',
'apiTestManagement.searchPlaceholder': 'Enter ID/name/api path search',
'apiTestManagement.searchTaskPlaceholder': 'Enter resource Id/name/URL search',
'apiTestManagement.apiName': 'Api name',
'apiTestManagement.apiType': 'Api type',
'apiTestManagement.shareModule': 'Share Module',
'apiTestManagement.doc': 'Documentation',
'apiTestManagement.closeAll': 'Close All Tabs',
'apiTestManagement.closeOther': 'Close Other Tabs',
'apiTestManagement.showSubdirectory': 'Show Subdirectory Cases',
'apiTestManagement.searchPlaceholder': 'Enter ID/Name/API Path to search',
'apiTestManagement.searchTaskPlaceholder': 'Enter Resource ID/Name/URL to search',
'apiTestManagement.apiName': 'API Name',
'apiTestManagement.apiType': 'Request Type',
'apiTestManagement.apiStatus': 'Status',
'apiTestManagement.path': 'Path',
'apiTestManagement.version': 'Version',
'apiTestManagement.createTime': 'Creation time',
'apiTestManagement.updateTime': 'Update time',
'apiTestManagement.deleteTime': 'Delete time',
'apiTestManagement.deleteUser': 'Delete user',
'apiTestManagement.createTime': 'Creation Time',
'apiTestManagement.updateTime': 'Update Time',
'apiTestManagement.deleteTime': 'Deletion Time',
'apiTestManagement.deleteUser': 'Deleted By',
'apiTestManagement.deprecate': 'Deprecated',
'apiTestManagement.processing': 'Processing',
'apiTestManagement.debugging': 'Debugging',
'apiTestManagement.done': 'Completed',
'apiTestManagement.deleteApiTipTitle': 'Are you sure you want to delete {name}?',
'apiTestManagement.done': 'Done',
'apiTestManagement.deleteApiTipTitle': 'Confirm to delete {name}?',
'apiTestManagement.deleteApiTip':
'After deletion, the interface will be placed in the recycle bin, where data recovery can be performed',
'apiTestManagement.batchDeleteApiTip': 'Are you sure you want to delete {count} selected interfaces?',
'apiTestManagement.batchModalSubTitle': '({count} interfaces selected)',
'apiTestManagement.chooseAttr': 'Select properties',
'apiTestManagement.attrRequired': 'Property cannot be empty',
'apiTestManagement.batchUpdate': 'Batch update to',
'apiTestManagement.valueRequired': 'Attribute value cannot be empty',
'After deletion, the API will be moved to the recycle bin and can be restored from there',
'apiTestManagement.batchDeleteApiTip': 'Confirm to delete the selected {count} APIs?',
'apiTestManagement.batchModalSubTitle': '(Selected {count} APIs)',
'apiTestManagement.chooseAttr': 'Choose Attribute',
'apiTestManagement.attrRequired': 'Attribute cannot be empty',
'apiTestManagement.batchUpdate': 'Batch Update to',
'apiTestManagement.valueRequired': 'Value cannot be empty',
'apiTestManagement.envRequired': 'Environment value cannot be empty',
'apiTestManagement.reportNameRequired': 'Report name cannot be empty',
'apiTestManagement.poolRequired': 'Resource pool cannot be empty',
'apiTestManagement.batchMoveConfirm': 'Move to selected module',
'apiTestManagement.belongModule': 'Belonging module',
'apiTestManagement.importMode': 'Import mode',
'apiTestManagement.belongModule': 'Belong to Module',
'apiTestManagement.importMode': 'Import Mode',
'apiTestManagement.importModeTip1': 'Cover:',
'apiTestManagement.importModeTip2':
'1.The same interface already exists in the system (the request type + path are consistent). If the request parameter content is inconsistent, the original interface of the system will be overwritten.',
'1. If the same API (same request type + path) already exists in the system and the request parameter content is different, it will overwrite the original API',
'apiTestManagement.importModeTip3':
'2.The same interface already exists in the system (request type + path are consistent), if the content of the request parameters is consistent, no changes will be made.',
'apiTestManagement.importModeTip4': '3.Interfaces that do not exist in the system are added.',
'apiTestManagement.importModeTip5': 'Not covered:',
'2. If the same API (same request type + path) already exists in the system and the request parameter content is the same, no changes will be made',
'apiTestManagement.importModeTip4': '3. If the API does not exist in the system, it will be added',
'apiTestManagement.importModeTip5': 'Do Not Cover:',
'apiTestManagement.importModeTip6':
'1.If the same interface already exists in the system (the request type + path is the same), no changes will be made.',
'apiTestManagement.importModeTip7': '2.Interfaces that do not exist in the system are added.',
'1. If the same API (same request type + path) already exists in the system, no changes will be made',
'apiTestManagement.importModeTip7': '2. If the API does not exist in the system, it will be added',
'apiTestManagement.cover': 'Cover',
'apiTestManagement.uncover': 'Not covered',
'apiTestManagement.moreSetting': 'More settings',
'apiTestManagement.importType': 'Import method',
'apiTestManagement.urlImport': 'URL import',
'apiTestManagement.syncImportCase': 'Synchronous import interface use case',
'apiTestManagement.syncUpdateDirectory': 'Synchronously update the directory where the interface is located',
'apiTestManagement.importSwaggerFileTip1': 'Supports json files of Swagger 3.0 version,',
'apiTestManagement.importSwaggerFileTip2': '2.0 files can be converted to 3.0 on the official website with one click',
'apiTestManagement.importSwaggerFileTip3': ', the size does not exceed 50M',
'apiTestManagement.urlImportPlaceholder': 'Please enter the OpenAPI/Swagger URL',
'apiTestManagement.swaggerURLRequired': 'SwaggerURL cannot be empty',
'apiTestManagement.basicAuth': 'Basic Authentication',
'apiTestManagement.uncover': 'Do Not Cover',
'apiTestManagement.moreSetting': 'More Settings',
'apiTestManagement.importType': 'Import Type',
'apiTestManagement.urlImport': 'URL Import',
'apiTestManagement.syncImportCase': 'Sync Import API Cases',
'apiTestManagement.syncUpdateDirectory': 'Sync Update API Directory',
'apiTestManagement.importSwaggerFileTip1': 'Supports Swagger 3.0 version JSON files,',
'apiTestManagement.importSwaggerFileTip2': '2.0 files can be converted to 3.0 on the official website',
'apiTestManagement.importSwaggerFileTip3': 'with a size limit of 50MB',
'apiTestManagement.urlImportPlaceholder': 'Please enter OpenAPI/URL',
'apiTestManagement.swaggerURLRequired': 'Swagger URL cannot be empty',
'apiTestManagement.basicAuth': 'Basic Auth',
'apiTestManagement.account': 'Account',
'apiTestManagement.accountRequired': 'Account cannot be empty',
'apiTestManagement.password': 'Password',
'apiTestManagement.passwordRequired': 'Password can not be blank',
'apiTestManagement.taskName': 'Task name',
'apiTestManagement.taskNamePlaceholder': 'Please enter a task name',
'apiTestManagement.passwordRequired': 'Password cannot be empty',
'apiTestManagement.taskName': 'Task Name',
'apiTestManagement.taskNamePlaceholder': 'Please enter task name',
'apiTestManagement.taskNameRequired': 'Task name cannot be empty',
'apiTestManagement.syncFrequency': 'Sync frequency',
'apiTestManagement.timeTaskList': 'Scheduled task list',
'apiTestManagement.timeTaskHour': '(per hour)',
'apiTestManagement.timeTaskSixHour': '(every 6 hours)',
'apiTestManagement.timeTaskTwelveHour': '(every 12 hours)',
'apiTestManagement.timeTaskDay': '(every day)',
'apiTestManagement.customFrequency': 'Custom frequency',
'apiTestManagement.syncFrequency': 'Sync Frequency',
'apiTestManagement.timeTaskList': 'Time Task List',
'apiTestManagement.timeTaskHour': '(Every Hour)',
'apiTestManagement.timeTaskSixHour': '(Every 6 Hours)',
'apiTestManagement.timeTaskTwelveHour': '(Every 12 Hours)',
'apiTestManagement.timeTaskDay': '(Every Day)',
'apiTestManagement.customFrequency': 'Custom Frequency',
'apiTestManagement.case': 'Case',
'apiTestManagement.definition': 'API',
'apiTestManagement.definition': 'Definition',
'apiTestManagement.debug': 'Debug',
'apiTestManagement.addDependency': 'Select dependency use case',
'apiTestManagement.clearSelected': 'Clear selected use cases',
'apiTestManagement.preDependency': 'Front interface',
'apiTestManagement.addPreDependency': 'Add pre-dependency',
'apiTestManagement.postDependency': 'Rear interface',
'apiTestManagement.addPostDependency': 'Add post-dependency',
'apiTestManagement.dependencyUnit': 'item',
'apiTestManagement.saveAsCase': 'Save as new use case',
'apiTestManagement.apiNamePlaceholder': 'Please enter the interface name',
'apiTestManagement.executeResult': 'Execution result',
'apiTestManagement.addDependency': 'Select Dependent Cases',
'apiTestManagement.clearSelected': 'Clear Selected Cases',
'apiTestManagement.preDependency': 'Pre-dependent API',
'apiTestManagement.addPreDependency': 'Add Pre-dependency',
'apiTestManagement.postDependency': 'Post-dependent API',
'apiTestManagement.addPostDependency': 'Add Post-dependency',
'apiTestManagement.dependencyUnit': 'unit(s)',
'apiTestManagement.saveAsCase': 'Save as New Case',
'apiTestManagement.apiNamePlaceholder': 'Please enter API name',
'apiTestManagement.executeResult': 'Execution Result',
'apiTestManagement.setDefault': 'Set as Default',
'apiTestManagement.confirmDelete': 'Are you sure you want to delete {name}?',
'apiTestManagement.response': 'Response{count}',
'apiTestManagement.responseCode': 'Response code',
'apiTestManagement.dynamicConversion': 'Dynamic conversion',
'apiTestManagement.expandApi': 'Show all requests',
'apiTestManagement.collapseApi': 'Hide all requests',
'apiTestManagement.paramName': 'Parameter name',
'apiTestManagement.paramVal': 'Parameter value',
'apiTestManagement.confirmDelete': 'Confirm to delete {name}?',
'apiTestManagement.response': 'Response {count}',
'apiTestManagement.responseCode': 'Response Code',
'apiTestManagement.dynamicConversion': 'Dynamic Conversion',
'apiTestManagement.expandApi': 'Show All Requests',
'apiTestManagement.collapseApi': 'Hide All Requests',
'apiTestManagement.paramName': 'Parameter Name',
'apiTestManagement.paramVal': 'Parameter Value',
'apiTestManagement.deleteMockTip':
'Deleting a mock expectation will cause the test task using the expectation to fail, so please operate with caution!',
'Deleting the expected response will cause the test task that uses it to fail. Please proceed with caution!',
'apiTestManagement.preview': 'Preview',
'apiTestManagement.shareUrlCopied': 'Sharing link copied to clipboard',
'apiTestManagement.shareUrlCopied': 'Share link has been copied to the clipboard',
'apiTestManagement.detail': 'Detail',
'apiTestManagement.reference': 'Reference',
'apiTestManagement.dependencies': 'Dependency',
'apiTestManagement.changeHistory': 'Change history',
'apiTestManagement.executeHistory': 'Execute history',
'apiTestManagement.requestParams': 'Request parameters',
'apiTestManagement.responseContent': 'Response content',
'apiTestManagement.requestHeader': 'Request header',
'apiTestManagement.requestBody': 'Request body',
'apiTestManagement.paramsType': 'Param type',
'apiTestManagement.dependencies': 'Dependencies',
'apiTestManagement.changeHistory': 'Change History',
'apiTestManagement.executeHistory': 'Execution History',
'apiTestManagement.requestParams': 'Request Parameters',
'apiTestManagement.responseContent': 'Response Content',
'apiTestManagement.requestHeader': 'Request Header',
'apiTestManagement.requestBody': 'Request Body',
'apiTestManagement.paramsType': 'Parameter Type',
'apiTestManagement.required': 'Required',
'apiTestManagement.requestData': 'Request data',
'apiTestManagement.apiNameRequired': 'Interface name cannot be empty',
'apiTestManagement.requestData': 'Request Data',
'apiTestManagement.apiNameRequired': 'API name cannot be empty',
'apiTestManagement.historyListTip':
'View and compare historical changes. According to the rules set by the administrator, the change history data will be automatically deleted.',
'apiTestManagement.changeOrder': 'Change serial number',
'apiTestManagement.order': 'Serial number',
"View and compare historical changes. According to the administrator's settings, historical data will be automatically deleted",
'apiTestManagement.changeOrder': 'Change Order',
'apiTestManagement.order': 'Order',
'apiTestManagement.type': 'Type',
'apiTestManagement.recover': 'Recover',
'apiTestManagement.quote': 'Quote',
'apiTestManagement.resourceName': 'Resource name',
'apiTestManagement.resourceType': 'Resource type',
'apiTestManagement.quoteType': 'Quote type',
'apiTestManagement.belongOrg': 'Organization',
'apiTestManagement.belongProject': 'Project',
'apiTestManagement.resourceName': 'Resource Name',
'apiTestManagement.resourceType': 'Resource Type',
'apiTestManagement.quoteType': 'Quote Type',
'apiTestManagement.belongOrg': 'Belong to Organization',
'apiTestManagement.belongProject': 'Belong to Project',
'apiTestManagement.quoteSearchPlaceholder': 'Enter ID or name to search',
'apiTestManagement.tableNoDataAndPlease': 'No data yet, please',
'apiTestManagement.click': 'Click',
'apiTestManagement.getResponse': 'Get Response Content',
'apiTestManagement.tableNoDataAndPlease': 'No data, please',
'apiTestManagement.or': 'or',
'apiTestManagement.document': 'Document',
'apiTestManagement.responseHeader': 'Response header',
'apiTestManagement.responseTime': 'Response time',
'apiTestManagement.document': 'Document Assertion',
'apiTestManagement.responseHeader': 'Response Header',
'apiTestManagement.responseTime': 'Response Time',
'apiTestManagement.script': 'Script',
'apiTestManagement.variable': 'Variable',
'apiTestManagement.regex': 'Regular',
'case.execute.selectEnv': 'Environmental choice',
'case.execute.defaultEnv': 'Default environment',
'case.execute.newEnv': 'New environment',
'case.execute.defaultEnvTip': 'The environment where the use case is saved',
'case.execute.model': 'Model',
'apiTestManagement.regex': 'Regular Expression',
'case.execute.selectEnv': 'Select Environment',
'case.execute.defaultEnv': 'Default Environment',
'case.execute.newEnv': 'New Environment',
'case.execute.defaultEnvTip': 'Environment saved with the case',
'case.execute.model': 'Mode',
'case.execute.serial': 'Serial',
'case.execute.parallel': 'Parallel',
'case.execute.StopOnFailure': 'Stop on failure',
'case.execute.reportSetting': 'Report configuration',
'case.execute.independentReporting': 'Independent reporting',
'case.execute.CollectionReport': 'Collection report',
'case.execute.reportName': 'Report name',
'case.execute.pool': 'Resource pool operation',
'case.allCase': 'All Case',
'case.execute.StopOnFailure': 'Stop on Failure',
'case.execute.reportSetting': 'Report Configuration',
'case.execute.independentReporting': 'Independent Reporting',
'case.execute.CollectionReport': 'Collection Report',
'case.execute.reportName': 'Report Name',
'case.execute.pool': 'Run in Resource Pool',
'case.allCase': 'All Cases',
'case.detail': 'Case Detail',
'case.caseName': 'Case Name',
'case.caseNameRequired': 'Case name cannot be empty',
'case.caseNamePlaceholder': 'Please enter case name',
'case.caseLevel': 'Case Level',
'case.caseEnvironment': 'Case Environment',
'case.tableColumnCreateUser': 'CreateUser',
'case.tableColumnCreateTime': 'CreateTime',
'case.tableColumnUpdateUser': 'UpdateUser',
'case.tableColumnUpdateTime': 'UpdateTime',
'case.lastReportStatus': 'Results Of Execution',
'case.passRate': 'Pass Rate',
'case.passRateTip': 'Number of success case executions/Total number of case executions *%',
'case.batchModalSubTitle': '({count} cases selected)',
'case.batchDeleteCaseTipTitle': 'Are you sure you want to delete {name} ',
'case.batchRecoverCaseTipTitle': 'Are you sure you want to recover {name} ',
'case.batchDeleteCaseTip': 'Are you sure you want to delete {count} selected cases?',
'case.tableColumnCreateUser': 'Created By',
'case.tableColumnCreateTime': 'Creation Time',
'case.tableColumnUpdateUser': 'Updated By',
'case.tableColumnUpdateTime': 'Update Time',
'case.lastReportStatus': 'Execution Result',
'case.passRate': 'Case Pass Rate',
'case.passRateTip': 'Success cases executed / Total cases executed *%',
'case.batchModalSubTitle': '(Selected {count} cases)',
'case.batchDeleteCaseTip': 'Confirm to delete the selected {count} cases?',
'case.batchDeleteCaseTipTitle': 'Confirm to delete {name}?',
'case.batchRecoverCaseTipTitle': 'Confirm to recover {name}?',
'case.recycle.cleanOutDeleteOnRecycleTip':
'After deletion, the case cannot be restored. Please operate with caution!',
'After deletion, the case cannot be recovered. Please proceed with caution!',
'case.deleteCaseTip':
'Deleting an case will result in the execution failure of the test task that references the use case. Please be cautious!',
'apiTestManagement.click': 'Click',
'apiTestManagement.getResponse': 'Get response content',
'case.batchRecoverCaseTip': 'Are you sure you want to recover {count} selected cases?',
'case.recycle.recoverCaseTip': 'When restoring the case, the deleted API will be restored simultaneously.',
'case.recycle.confirmRecovery': 'Confirm recovery',
'Deleting the case will cause the test task that references it to fail. Please proceed with caution!',
'case.batchRecoverCaseTip': 'Confirm to recover the selected {count} cases?',
'case.recycle.recoverCaseTip': 'Recovering the case will also restore the deleted API',
'case.recycle.confirmRecovery': 'Confirm Recovery',
'case.createCase': 'Create Case',
'case.updateCase': 'Update Case',
'case.saveContinueText': 'Save & continue',
'case.detail.changeHistoryTip': `View and compare historical changes. According to the administrator's setting rules, historical changes will be automatically deleted`,
'case.detail.noReminders': 'No longer remind',
'case.detail.changeNumber': 'Change sequence',
'case.detail.changeType': 'type',
'case.detail.operator': 'operator',
'case.detail.tableColumnUpdateTime': 'UpdateTime',
'case.detail.execute.success': 'Execute success',
'case.detail.execute.history.list': 'Execution history list',
'case.detail.dependency.list': 'Reference relationship list',
'case.detail.resource.api': 'API',
'case.detail.report.delete': 'Report cleared',
'mockManagement.name': 'Expected name',
'mockManagement.apiPath': 'Interface path',
'case.saveContinueText': 'Save and Continue Creating',
'case.detail.changeHistoryTip':
"View and compare historical changes. According to the administrator's settings, historical data will be automatically deleted",
'case.detail.noReminders': 'Do not remind again',
'case.detail.changeNumber': 'Change Number',
'case.detail.changeType': 'Change Type',
'case.detail.operator': 'Operator',
'case.detail.tableColumnUpdateTime': 'Update Time',
'case.detail.execute.success': 'Execution Successful',
'case.detail.execute.history.list': 'Execution History List',
'case.detail.dependency.list': 'Dependency List',
'case.detail.resource.api': 'API Test',
'case.detail.report.delete': 'Report has been cleared',
'mockManagement.name': 'Expectation Name',
'mockManagement.apiPath': 'API Path',
'mockManagement.operationUser': 'Operator',
'mockManagement.updateTime': 'Update time',
'mockManagement.copyMock': 'Copy mock address',
'mockManagement.batchEnable': 'Batch enable',
'mockManagement.batchDisEnable': 'Batch disable',
'mockManagement.batchDeleteMockTip': 'Are you sure you want to delete the selected {count} mocks?',
'mockManagement.allMock': 'All MOCK',
'mockManagement.updateTime': 'Update Time',
'mockManagement.copyMock': 'Copy Mock URL',
'mockManagement.batchEnable': 'Batch Enable',
'mockManagement.batchDisEnable': 'Batch Disable',
'mockManagement.batchDeleteMockTip': 'Confirm to delete the selected {count} mocks?',
'mockManagement.allMock': 'All Mocks',
'mockManagement.createMock': 'Create Mock',
'mockManagement.updateMock': 'Update Mock',
'mockManagement.mockDetail': 'Mock Detail',
'mockManagement.namePlaceholder': 'Please enter expectation name',
'mockManagement.nameNotNull': 'Expectation name cannot be empty',
'mockManagement.matchRule': 'Match Rule',
'mockManagement.saveAndContinue': 'Save and Continue Creating',
'mockManagement.paramNameNotNull': 'Parameter name cannot be empty',
'mockManagement.followDefinition': 'Follow API Definition',
'mockManagement.equals': 'Equals',
'mockManagement.notEquals': 'Not Equals',
'mockManagement.lengthEquals': 'Length Equals',
'mockManagement.lengthLarge': 'Length Larger Than',
'mockManagement.lengthLess': 'Length Less Than',
'mockManagement.lengthNotEquals': 'Length Not Equals',
'mockManagement.contain': 'Contain',
'mockManagement.notContain': 'Not Contain',
'mockManagement.empty': 'Empty',
'mockManagement.notEmpty': 'Not Empty',
'mockManagement.regular': 'Regular Expression',
'mockManagement.batchEdit': 'Batch Edit',
'mockManagement.batchDelete': 'Batch Delete',
'mockManagement.noMatchRules': 'No matching rules found',
};

View File

@ -237,4 +237,5 @@ export default {
'mockManagement.regular': '正则匹配',
'mockManagement.batchEdit': '批量编辑',
'mockManagement.batchDelete': '批量删除',
'mockManagement.noMatchRules': '无该类匹配规则',
};

View File

@ -128,7 +128,7 @@ export default {
'system.config.auth.nameRequired': 'Authentication source name cannot be empty',
'system.config.auth.namePlaceholder': 'Please enter the authentication source name',
'system.config.auth.descPlaceholder': 'Please describe the certification source',
'system.config.auth.addResource': 'Add resource',
'system.config.auth.addResource': 'Add auth',
'system.config.auth.serviceUrl': 'Server address',
'system.config.auth.serviceUrlRequired': 'Server address cannot be empty',
'system.config.auth.commonUrlPlaceholder': 'eg: {url}',

View File

@ -124,7 +124,7 @@ export default {
'system.config.auth.nameRequired': '认证源名称不能为空',
'system.config.auth.namePlaceholder': '请输入认证源名称',
'system.config.auth.descPlaceholder': '请对该认证源进行描述',
'system.config.auth.addResource': '添加资源',
'system.config.auth.addResource': '添加认证',
'system.config.auth.serviceUrl': '服务端地址',
'system.config.auth.serviceUrlRequired': '服务端地址不能为空',
'system.config.auth.commonUrlPlaceholder': '例如:{url}',