fix(接口场景): 引用API参数值写入&调整引用API/CASE请求参数tab显示

This commit is contained in:
teukkk 2024-03-26 13:04:48 +08:00 committed by Craftsman
parent d6a0932361
commit 5e53eaa84f
9 changed files with 164 additions and 56 deletions

View File

@ -12,7 +12,7 @@
<paramsTable
ref="extractParamsTableRef"
v-model:params="condition.jsonPathAssertion.assertions"
:disabled="props.disabled"
:disabled-except-param="props.disabled"
:selectable="false"
:columns="jsonPathColumns"
:scroll="{ minWidth: '700px' }"
@ -105,7 +105,7 @@
<paramsTable
ref="extractParamsTableRef"
v-model:params="condition.xpathAssertion.assertions"
:disabled="props.disabled"
:disabled-except-param="props.disabled"
:selectable="false"
:columns="xPathColumns"
:scroll="{ minWidth: '700px' }"
@ -200,7 +200,7 @@
<div class="mt-[16px]">
<paramsTable
v-model:params="condition.document.jsonAssertion"
:disabled="props.disabled"
:disabled-except-param="props.disabled"
:selectable="false"
:columns="documentColumns"
:scroll="{
@ -253,7 +253,7 @@
ref="extractParamsTableRef"
v-model:params="condition.regexAssertion.assertions"
:selectable="false"
:disabled="props.disabled"
:disabled-except-param="props.disabled"
:columns="xPathColumns"
:scroll="{ minWidth: '700px' }"
:default-param-item="xPathDefaultParamItem"

View File

@ -6,7 +6,7 @@
:columns="columns"
:scroll="{ minWidth: '700px' }"
:default-param-item="defaultParamItem"
:disabled="props.disabled"
:disabled-except-param="props.disabled"
@change="handleParamTableChange"
/>
</div>

View File

@ -5,6 +5,7 @@
:columns="columns"
:scroll="{ minWidth: '700px' }"
:default-param-item="defaultParamItem"
:disabled-except-param="props.disabled"
@change="handleParamTableChange"
/>
</template>
@ -24,6 +25,7 @@
const props = defineProps<{
data: Param;
disabled?: boolean;
}>();
const emit = defineEmits<{

View File

@ -49,7 +49,7 @@
<span class="ms-assertion-body-left-item-row-title">{{ item.name }}</span>
</div>
<div class="ms-assertion-body-left-item-switch">
<div class="ms-assertion-body-left-item-switch-action">
<div v-show="!props.disabled" class="ms-assertion-body-left-item-switch-action">
<MsIcon
type="icon-icon_drag"
class="action-btn-move sort-handle cursor-move text-[12px] text-[var(--color-text-4)]"

View File

@ -256,6 +256,7 @@
<div class="mb-[8px] text-[var(--color-text-1)]">{{ t('common.desc') }}</div>
<a-input
v-model:model-value="condition.name"
:disabled="props.disabled"
:placeholder="t('apiTestDebug.commonPlaceholder')"
:max-length="255"
@input="() => emit('change')"
@ -266,7 +267,12 @@
{{ condition.dataSourceName || '-' }}
</div>
<a-divider margin="8px" direction="vertical" />
<MsButton type="text" class="font-medium" @click="quoteSqlSourceDrawerVisible = true">
<MsButton
type="text"
class="font-medium"
:disabled="props.disabled"
@click="quoteSqlSourceDrawerVisible = true"
>
{{ t('apiTestDebug.introduceSource') }}
</MsButton>
</div>
@ -297,6 +303,7 @@
<a-input
v-model:model-value="condition.variableNames"
:max-length="255"
:disabled="props.disabled"
:placeholder="t('apiTestDebug.storageByColPlaceholder', { a: '{id_1}', b: '{username_1}' })"
@input="() => emit('change')"
/>
@ -313,6 +320,7 @@
</div>
<paramTable
:params="condition.extractParams"
:disabled-except-param="props.disabled"
:columns="sqlSourceColumns"
:selectable="false"
:default-param-item="defaultKeyValueParamItem"
@ -323,6 +331,7 @@
<div class="mb-[8px] text-[var(--color-text-1)]">{{ t('apiTestDebug.storageByResult') }}</div>
<a-input
v-model:model-value="condition.resultVariable"
:disabled="props.disabled"
:max-length="255"
:placeholder="t('apiTestDebug.storageByResultPlaceholder', { a: '${result}' })"
@input="() => emit('change')"
@ -351,6 +360,7 @@
<paramTable
ref="extractParamsTableRef"
:params="condition.extractors"
:disabled-except-param="props.disabled"
:default-param-item="defaultExtractParamItem"
:columns="extractParamsColumns"
:selectable="false"
@ -380,6 +390,7 @@
:max-length="255"
:placeholder="t('ms.paramsInput.commonPlaceholder')"
size="mini"
:disabled="props.disabled"
@input="() => handleExpressionChange(rowIndex)"
@change="() => handleExpressionChange(rowIndex)"
>
@ -394,7 +405,9 @@
type="icon-icon_flashlamp"
:size="15"
:class="
disabledExpressionSuffix ? 'ms-params-input-suffix-icon--disabled' : 'ms-params-input-suffix-icon'
disabledExpressionSuffix || props.disabled
? 'ms-params-input-suffix-icon--disabled'
: 'ms-params-input-suffix-icon'
"
@click.stop="() => showFastExtraction(record)"
/>
@ -828,6 +841,7 @@ if (!result){
const activeRecord = ref({ ...defaultExtractParamItem }); //
function showFastExtraction(record: ExpressionConfig) {
if (props.disabled) return;
activeRecord.value = { ...record };
fastExtractionVisible.value = true;
}

View File

@ -237,42 +237,80 @@
label: t('apiTestDebug.setting'),
},
];
const headerNum = computed(
() => filterKeyValParams(requestVModel.value?.headers ?? [], defaultHeaderParamsItem).validParams?.length
);
const restNum = computed(
() => filterKeyValParams(requestVModel.value?.rest ?? [], defaultRequestParamsItem).validParams?.length
);
const queryNum = computed(
() => filterKeyValParams(requestVModel.value?.query ?? [], defaultRequestParamsItem).validParams?.length
);
const preProcessorNum = computed(() => requestVModel.value.children[0].preProcessorConfig.processors.length);
const postProcessorNum = computed(() => requestVModel.value.children[0].postProcessorConfig.processors.length);
const assertionsNum = computed(() => requestVModel.value.children[0].assertionConfig.assertions.length);
// tab
const contentTabList = computed(() => {
// HTTP tabs
if (isHttpProtocol.value) {
// CASE[queryrest]tab
if (props.disabledExceptParam) {
return httpContentTabList.filter(
(item) =>
!(!restNum.value && item.value === RequestComposition.REST) &&
!(!queryNum.value && item.value === RequestComposition.QUERY) &&
!(!headerNum.value && item.value === RequestComposition.HEADER) &&
!(!preProcessorNum.value && item.value === RequestComposition.PRECONDITION) &&
!(!postProcessorNum.value && item.value === RequestComposition.POST_CONDITION) &&
!(!assertionsNum.value && item.value === RequestComposition.ASSERTION)
);
}
return props.isShowCommonContentTabKey
? httpContentTabList
: httpContentTabList.filter((e) => !commonContentTabKey.includes(e.value));
}
if (props.disabledExceptParam) {
return [
...pluginContentTab,
...httpContentTabList
.filter((e) => commonContentTabKey.includes(e.value))
.filter(
(item) =>
!(!preProcessorNum.value && item.value === RequestComposition.PRECONDITION) &&
!(!postProcessorNum.value && item.value === RequestComposition.POST_CONDITION) &&
!(!assertionsNum.value && item.value === RequestComposition.ASSERTION)
),
];
}
return [...pluginContentTab, ...httpContentTabList.filter((e) => commonContentTabKey.includes(e.value))];
});
// tab
function getTabBadge(tabKey: RequestComposition) {
switch (tabKey) {
case RequestComposition.HEADER:
const headerNum = filterKeyValParams(requestVModel.value.headers, defaultHeaderParamsItem).validParams.length;
return `${headerNum > 0 ? headerNum : ''}`;
return `${headerNum.value > 0 ? headerNum.value : ''}`;
case RequestComposition.BODY:
return requestVModel.value.body?.bodyType !== RequestBodyFormat.NONE ? '1' : '';
case RequestComposition.QUERY:
const queryNum = filterKeyValParams(requestVModel.value.query, defaultRequestParamsItem).validParams.length;
return `${queryNum > 0 ? queryNum : ''}`;
return `${queryNum.value > 0 ? queryNum.value : ''}`;
case RequestComposition.REST:
const restNum = filterKeyValParams(requestVModel.value.rest, defaultRequestParamsItem).validParams.length;
return `${restNum > 0 ? restNum : ''}`;
return `${restNum.value > 0 ? restNum.value : ''}`;
case RequestComposition.PRECONDITION:
return `${requestVModel.value.children[0].preProcessorConfig.processors.length || ''}`;
return `${preProcessorNum.value > 99 ? '99+' : preProcessorNum.value || ''}`;
case RequestComposition.POST_CONDITION:
return `${requestVModel.value.children[0].postProcessorConfig.processors.length || ''}`;
return `${postProcessorNum.value > 99 ? '99+' : postProcessorNum.value || ''}`;
case RequestComposition.ASSERTION:
return `${requestVModel.value.children[0].assertionConfig.assertions.length || ''}`;
return `${assertionsNum.value > 99 ? '99+' : assertionsNum.value || ''}`;
case RequestComposition.AUTH:
return requestVModel.value.authConfig.authType !== RequestAuthType.NONE ? '1' : '';
default:
return '';
}
}
// tabtab
function setActiveTabByFirst() {
requestVModel.value.activeTab = contentTabList.value[0].value;
}
const protocolLoading = ref(false);
const protocolOptions = ref<SelectOptionData[]>([]);
@ -492,6 +530,7 @@
initPluginScript,
handleActiveDebugChange,
makeRequestParams,
setActiveTabByFirst,
});
</script>

View File

@ -64,7 +64,7 @@
/>
<MsAddAttachment
v-model:file-list="fileList"
:disabled="props.disabledExceptParam"
:disabled="props.disabledParamValue"
mode="input"
:multiple="false"
:fields="{

View File

@ -475,6 +475,11 @@
}
return t('apiScenario.customApi');
});
// api props.request
const isCopyApiNeedInit = computed(() => _stepType.value.isCopyApi && props.request === undefined);
const isEditableApi = computed(
() => _stepType.value.isCopyApi || props.step?.stepType === ScenarioStepType.CUSTOM_REQUEST || !props.step
);
const isHttpProtocol = computed(() => requestVModel.value.protocol === 'HTTP');
const temporaryResponseMap = {}; // websockettab
const isInitPluginForm = ref(false);
@ -538,12 +543,49 @@
label: t('apiTestDebug.setting'),
},
];
const headerNum = computed(
() => filterKeyValParams(requestVModel.value?.headers ?? [], defaultHeaderParamsItem).validParams?.length
);
const restNum = computed(
() => filterKeyValParams(requestVModel.value?.rest ?? [], defaultRequestParamsItem).validParams?.length
);
const queryNum = computed(
() => filterKeyValParams(requestVModel.value?.query ?? [], defaultRequestParamsItem).validParams?.length
);
const preProcessorNum = computed(() => requestVModel.value.children[0].preProcessorConfig.processors.length);
const postProcessorNum = computed(() => requestVModel.value.children[0].postProcessorConfig.processors.length);
const assertionsNum = computed(() => requestVModel.value.children[0].assertionConfig.assertions.length);
// tab
const contentTabList = computed(() => {
// HTTP tabs
if (isHttpProtocol.value) {
// APIqueryresttab
if (!isEditableApi.value) {
return httpContentTabList.filter(
(item) =>
!(!restNum.value && item.value === RequestComposition.REST) &&
!(!queryNum.value && item.value === RequestComposition.QUERY) &&
!(!headerNum.value && item.value === RequestComposition.HEADER) &&
!(!preProcessorNum.value && item.value === RequestComposition.PRECONDITION) &&
!(!postProcessorNum.value && item.value === RequestComposition.POST_CONDITION) &&
!(!assertionsNum.value && item.value === RequestComposition.ASSERTION)
);
}
return httpContentTabList;
}
if (!isEditableApi.value) {
return [
...pluginContentTab,
...httpContentTabList
.filter((e) => commonContentTabKey.includes(e.value))
.filter(
(item) =>
!(!preProcessorNum.value && item.value === RequestComposition.PRECONDITION) &&
!(!postProcessorNum.value && item.value === RequestComposition.POST_CONDITION) &&
!(!assertionsNum.value && item.value === RequestComposition.ASSERTION)
),
];
}
return [...pluginContentTab, ...httpContentTabList.filter((e) => commonContentTabKey.includes(e.value))];
});
@ -553,34 +595,19 @@
function getTabBadge(tabKey: RequestComposition) {
switch (tabKey) {
case RequestComposition.HEADER:
const headerNum = filterKeyValParams(requestVModel.value.headers, defaultHeaderParamsItem).validParams.length;
return `${headerNum > 0 ? headerNum : ''}`;
return `${headerNum.value > 0 ? headerNum.value : ''}`;
case RequestComposition.BODY:
return requestVModel.value.body?.bodyType !== RequestBodyFormat.NONE ? '1' : '';
case RequestComposition.QUERY:
const queryNum = filterKeyValParams(requestVModel.value.query, defaultRequestParamsItem).validParams.length;
return `${queryNum > 0 ? queryNum : ''}`;
return `${queryNum.value > 0 ? queryNum.value : ''}`;
case RequestComposition.REST:
const restNum = filterKeyValParams(requestVModel.value.rest, defaultRequestParamsItem).validParams.length;
return `${restNum > 0 ? restNum : ''}`;
return `${restNum.value > 0 ? restNum.value : ''}`;
case RequestComposition.PRECONDITION:
return `${
requestVModel.value.children[0].preProcessorConfig.processors.length > 99
? '99+'
: requestVModel.value.children[0].preProcessorConfig.processors.length || ''
}`;
return `${preProcessorNum.value > 99 ? '99+' : preProcessorNum.value || ''}`;
case RequestComposition.POST_CONDITION:
return `${
requestVModel.value.children[0].postProcessorConfig.processors.length > 99
? '99+'
: requestVModel.value.children[0].postProcessorConfig.processors.length || ''
}`;
return `${postProcessorNum.value > 99 ? '99+' : postProcessorNum.value || ''}`;
case RequestComposition.ASSERTION:
return `${
requestVModel.value.children[0].assertionConfig.assertions.length > 99
? '99+'
: requestVModel.value.children[0].assertionConfig.assertions.length || ''
}`;
return `${assertionsNum.value > 99 ? '99+' : assertionsNum.value || ''}`;
case RequestComposition.AUTH:
return requestVModel.value.authConfig.authType !== RequestAuthType.NONE ? '1' : '';
default:
@ -623,11 +650,6 @@
const currentPluginScript = computed<Record<string, any>[]>(
() => pluginScriptMap.value[requestVModel.value.protocol]?.script || []
);
// api props.request
const isCopyApiNeedInit = computed(() => _stepType.value.isCopyApi && props.request === undefined);
const isEditableApi = computed(
() => _stepType.value.isCopyApi || props.step?.stepType === ScenarioStepType.CUSTOM_REQUEST || !props.step
);
//
const handlePluginFormChange = debounce(() => {
@ -1045,7 +1067,37 @@
resourceId: res.id,
...parseRequestBodyResult,
};
if (_stepType.value.isQuoteApi && props.request && isHttpProtocol.value) {
// queryrest
['headers', 'query', 'rest'].forEach((type) => {
props.request?.[type]?.forEach((item) => {
if (!item.key.length) return;
const index = requestVModel.value[type]?.findIndex((itemReq) => itemReq.key === item.key);
// key;key
if (index > -1) {
requestVModel.value[type][index].value = item.value;
} else {
requestVModel.value[type].push(item);
}
});
});
['formDataBody', 'wwwFormBody'].forEach((type) => {
props.request?.body?.[type].formValues.forEach((item) => {
if (!item.key.length) return;
const index = requestVModel.value.body[type].formValues.findIndex((itemReq) => itemReq.key === item.key);
if (index > -1) {
requestVModel.value.body[type].formValues[index].value = item.value;
} else {
requestVModel.value.body[type].formValues.push(item);
}
});
});
if (props.request?.body.binaryBody.file) {
requestVModel.value.body.binaryBody.file = props.request?.body.binaryBody.file;
}
}
nextTick(() => {
requestVModel.value.activeTab = contentTabList.value[0].value;
// loading
loading.value = false;
});

View File

@ -5,7 +5,7 @@
:mask="false"
:width="900"
:footer="false"
:show-full-screen="!isShowEditStepNameInput"
show-full-screen
no-content-padding
@close="handleClose"
>
@ -67,7 +67,7 @@
:disabled-param-value="isQuote"
:request="requestVModel"
:is-priority-local-exec="isPriorityLocalExec"
:file-save-as-source-id="requestVModel.id"
:file-save-as-source-id="requestVModel.resourceId"
:file-module-options-api="getTransferOptionsCase"
:file-save-as-api="transferFileCase"
:upload-temp-file="uploadTempFileCase"
@ -133,6 +133,7 @@
const defaultCaseParams: RequestParam = {
id: `case-${Date.now()}`,
resourceId: '',
type: 'case',
moduleId: 'root',
protocol: 'HTTP',
@ -203,7 +204,7 @@
() =>
activeStep.value?.stepType === ScenarioStepType.API_CASE && activeStep.value?.refType === ScenarioStepRefType.COPY
);
const isCopyNeedInit = computed(() => isCopyCase.value && props.request?.request === null);
const isCopyNeedInit = computed(() => isCopyCase.value && props.request === undefined);
const isQuote = computed(
() =>
activeStep.value?.stepType === ScenarioStepType.API_CASE && activeStep.value?.refType === ScenarioStepRefType.REF
@ -280,10 +281,11 @@
debugSocket(executeType); // websocket
let res;
const params = {
apiDefinitionId: requestVModel.value.apiDefinitionId,
...makeRequestParams,
reportId: reportId.value,
};
if (!(requestVModel.value.id as string).startsWith('c') && executeType === 'serverExec') {
if (!(requestVModel.value.resourceId as string).startsWith('c') && executeType === 'serverExec') {
//
res = await runCase(params);
} else {
@ -317,7 +319,7 @@
async function initQuoteCaseDetail() {
try {
loading.value = true;
const res = await getCaseDetail(props.request?.id as string);
const res = await getCaseDetail(activeStep.value?.resourceId || '');
let parseRequestBodyResult;
if (res.protocol === 'HTTP') {
parseRequestBodyResult = parseRequestBodyFiles(res.request.body); // id
@ -334,10 +336,11 @@
response: cloneDeep(defaultResponse),
url: res.path,
name: res.name, // requestnamenull
id: res.id,
resourceId: res.id,
...parseRequestBodyResult,
};
nextTick(() => {
requestAndResponseRef.value?.setActiveTabByFirst();
// loading
loading.value = false;
});
@ -352,12 +355,10 @@
() => visible.value,
async (val) => {
if (val) {
if (props.request) {
requestVModel.value = { ...cloneDeep(defaultCaseParams), ...props.request };
if (isQuote.value || isCopyNeedInit.value) {
// (request.requestrequest null)
initQuoteCaseDetail();
}
requestVModel.value = { ...cloneDeep(defaultCaseParams), ...props.request };
if (isQuote.value || isCopyNeedInit.value) {
// (request.requestrequest null)
initQuoteCaseDetail();
}
await initLocalConfig();
}