feat(项目管理): 环境管理断言不包括响应体
This commit is contained in:
parent
45929cd675
commit
b491c783ad
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<paramsTable
|
<paramsTable
|
||||||
v-model:params="innerParams"
|
v-model:params="condition.assertions"
|
||||||
:selectable="false"
|
:selectable="false"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:scroll="{ minWidth: '700px' }"
|
:scroll="{ minWidth: '700px' }"
|
||||||
|
@ -12,25 +12,32 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineModel } from 'vue';
|
import { useVModel } from '@vueuse/core';
|
||||||
|
|
||||||
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
||||||
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||||
|
|
||||||
|
import type { ExecuteAssertionItem } from '@/models/apiTest/common';
|
||||||
|
|
||||||
interface Param {
|
interface Param {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
assertions: ExecuteAssertionItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const innerParams = defineModel<Param[]>('modelValue', { default: [] });
|
const props = defineProps<{
|
||||||
|
data: Param;
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'change', val: any[]): void; // 数据发生变化
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'change', data: Param): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const condition = useVModel(props, 'data', emit);
|
||||||
|
|
||||||
const defaultParamItem = {
|
const defaultParamItem = {
|
||||||
responseHeader: '',
|
header: '',
|
||||||
matchCondition: '',
|
condition: '',
|
||||||
matchValue: '',
|
expectedValue: '',
|
||||||
enable: true,
|
enable: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,24 +59,24 @@
|
||||||
const columns: ParamTableColumn[] = [
|
const columns: ParamTableColumn[] = [
|
||||||
{
|
{
|
||||||
title: 'ms.assertion.responseHeader', // 响应头
|
title: 'ms.assertion.responseHeader', // 响应头
|
||||||
dataIndex: 'responseHeader',
|
dataIndex: 'header',
|
||||||
slotName: 'responseHeader',
|
slotName: 'header',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
options: responseHeaderOption,
|
options: responseHeaderOption,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'ms.assertion.matchCondition', // 匹配条件
|
title: 'ms.assertion.matchCondition', // 匹配条件
|
||||||
dataIndex: 'matchCondition',
|
dataIndex: 'condition',
|
||||||
slotName: 'matchCondition',
|
slotName: 'condition',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
options: statusCodeOptions,
|
options: statusCodeOptions,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'ms.assertion.matchValue', // 匹配值
|
title: 'ms.assertion.matchValue', // 匹配值
|
||||||
dataIndex: 'matchValue',
|
dataIndex: 'expectedValue',
|
||||||
slotName: 'matchValue',
|
slotName: 'expectedValue',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
},
|
},
|
||||||
|
@ -82,10 +89,11 @@
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function handleParamTableChange(resultArr: any[], isInit?: boolean) {
|
function handleParamTableChange(resultArr: any[], isInit?: boolean) {
|
||||||
innerParams.value = [...resultArr];
|
condition.value.assertions = [...resultArr];
|
||||||
if (!isInit) {
|
if (!isInit) {
|
||||||
emit('change', resultArr);
|
emit('change', { ...condition.value });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,29 +4,37 @@
|
||||||
<span class="text-[var(--color-text-1)]">{{ t('ms.assertion.responseTime') }}</span>
|
<span class="text-[var(--color-text-1)]">{{ t('ms.assertion.responseTime') }}</span>
|
||||||
<span class="text-[var(--color-text-4)]">(ms)</span>
|
<span class="text-[var(--color-text-4)]">(ms)</span>
|
||||||
</div>
|
</div>
|
||||||
<a-input-number v-model:model-value="innerParams" :step="100" mode="button" />
|
<a-input-number
|
||||||
|
v-model="condition.expectedValue"
|
||||||
|
:step="100"
|
||||||
|
mode="button"
|
||||||
|
@blur="
|
||||||
|
emit('change', {
|
||||||
|
...condition,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
import { ExecuteAssertion } from '../type';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
interface ResponseTimeTabProps {
|
|
||||||
responseTime: number;
|
|
||||||
}
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
value: ResponseTimeTabProps;
|
data: ExecuteAssertion;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const innerParams = ref(props.value.responseTime);
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'change', val: ResponseTimeTabProps): void; // 数据发生变化
|
(e: 'change', data: ExecuteAssertion): void;
|
||||||
}>();
|
}>();
|
||||||
watchEffect(() => {
|
|
||||||
emit('change', { responseTime: innerParams.value });
|
const condition = useVModel(props, 'data', emit);
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-[8px]">{{ t('ms.assertion.statusCode') }}</div>
|
<div class="mb-[8px]">{{ t('ms.assertion.statusCode') }}</div>
|
||||||
<a-select
|
<a-select
|
||||||
v-model="selectValue"
|
v-model="condition.condition"
|
||||||
class="w-[157px]"
|
class="w-[157px]"
|
||||||
@change="
|
@change="
|
||||||
emit('change', {
|
emit('change', {
|
||||||
statusCode: statusCode,
|
...condition,
|
||||||
selectValue: selectValue,
|
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -17,15 +16,14 @@
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</div>
|
</div>
|
||||||
<a-input-number
|
<a-input
|
||||||
v-if="showInput"
|
v-if="showInput"
|
||||||
v-model:modelValue="statusCode"
|
v-model="condition.expectedValue"
|
||||||
hide-button
|
hide-button
|
||||||
class="w-[157px]"
|
class="w-[157px]"
|
||||||
@change="
|
@change="
|
||||||
emit('change', {
|
emit('change', {
|
||||||
statusCode: statusCode,
|
...condition,
|
||||||
selectValue: selectValue,
|
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
|
@ -34,28 +32,30 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
|
|
||||||
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
interface Param {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
assertionType: string;
|
||||||
|
condition: string;
|
||||||
|
expectedValue: string;
|
||||||
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
value: {
|
data: Param;
|
||||||
statusCode: number;
|
|
||||||
selectValue: string;
|
|
||||||
};
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits(['change']);
|
const emit = defineEmits<{
|
||||||
const selectValue = ref<string>('');
|
(e: 'change', data: Param): void;
|
||||||
const statusCode = ref<number>(200);
|
}>();
|
||||||
const showInput = computed(() => selectValue.value !== 'none' && selectValue.value !== '');
|
const condition = useVModel(props, 'data', emit);
|
||||||
|
const showInput = computed(() => condition.value.condition !== 'none' && condition.value.condition !== '');
|
||||||
const { t } = useI18n();
|
|
||||||
watchEffect(() => {
|
|
||||||
selectValue.value = props.value.selectValue;
|
|
||||||
statusCode.value = props.value.statusCode;
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<paramsTable
|
<paramsTable
|
||||||
v-model:params="innerParams"
|
v-model:params="condition.variableAssertionItems"
|
||||||
:selectable="false"
|
:selectable="false"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:scroll="{ minWidth: '700px' }"
|
:scroll="{ minWidth: '700px' }"
|
||||||
|
@ -10,27 +10,30 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
|
|
||||||
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
||||||
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||||
|
|
||||||
interface Param {
|
interface Param {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
variableAssertionItems: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
value?: Param[];
|
data: Param;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const innerParams = ref(props.value || []);
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'change'): void; // 数据发生变化
|
(e: 'change', data: Param): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const condition = useVModel(props, 'data', emit);
|
||||||
|
|
||||||
const defaultParamItem = {
|
const defaultParamItem = {
|
||||||
responseHeader: '',
|
variableName: '',
|
||||||
matchCondition: '',
|
condition: '',
|
||||||
matchValue: '',
|
expectedValue: '',
|
||||||
enable: true,
|
enable: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +55,7 @@
|
||||||
const columns: ParamTableColumn[] = [
|
const columns: ParamTableColumn[] = [
|
||||||
{
|
{
|
||||||
title: 'ms.assertion.variableName', // 变量名
|
title: 'ms.assertion.variableName', // 变量名
|
||||||
dataIndex: 'key',
|
dataIndex: 'variableName',
|
||||||
slotName: 'key',
|
slotName: 'key',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
|
@ -60,16 +63,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'ms.assertion.matchCondition', // 匹配条件
|
title: 'ms.assertion.matchCondition', // 匹配条件
|
||||||
dataIndex: 'matchCondition',
|
dataIndex: 'condition',
|
||||||
slotName: 'matchCondition',
|
slotName: 'condition',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
options: statusCodeOptions,
|
options: statusCodeOptions,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'ms.assertion.matchValue', // 匹配值
|
title: 'ms.assertion.matchValue', // 匹配值
|
||||||
dataIndex: 'value',
|
dataIndex: 'expectedValue',
|
||||||
slotName: 'value',
|
slotName: 'expectedValue',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
},
|
},
|
||||||
|
@ -83,9 +86,9 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
function handleParamTableChange(resultArr: any[], isInit?: boolean) {
|
function handleParamTableChange(resultArr: any[], isInit?: boolean) {
|
||||||
innerParams.value = [...resultArr];
|
condition.value.variableAssertionItems = [...resultArr];
|
||||||
if (!isInit) {
|
if (!isInit) {
|
||||||
emit('change');
|
emit('change', { ...condition.value });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
<div v-if="showBody" class="ms-assertion-body">
|
<div v-if="showBody" class="ms-assertion-body">
|
||||||
<VueDraggable v-model="selectItems" class="ms-assertion-body-left" ghost-class="ghost" handle=".sort-handle">
|
<VueDraggable v-model="assertions" class="ms-assertion-body-left" ghost-class="ghost" handle=".sort-handle">
|
||||||
<div
|
<div
|
||||||
v-for="(item, index) in selectItems"
|
v-for="(item, index) in assertions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="ms-assertion-body-left-item"
|
class="ms-assertion-body-left-item"
|
||||||
:class="{
|
:class="{
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
>
|
>
|
||||||
<div class="ms-assertion-body-left-item-row">
|
<div class="ms-assertion-body-left-item-row">
|
||||||
<span class="ms-assertion-body-left-item-row-num">{{ index + 1 }}</span>
|
<span class="ms-assertion-body-left-item-row-num">{{ index + 1 }}</span>
|
||||||
<span class="ms-assertion-body-left-item-row-title">{{ item.label }}</span>
|
<span class="ms-assertion-body-left-item-row-title">{{ item.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ms-assertion-body-left-item-switch">
|
<div class="ms-assertion-body-left-item-switch">
|
||||||
<div class="ms-assertion-body-left-item-switch-action">
|
<div class="ms-assertion-body-left-item-switch-action">
|
||||||
|
@ -50,40 +50,46 @@
|
||||||
</MsTableMoreAction>
|
</MsTableMoreAction>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-switch type="line" size="small" />
|
<a-switch v-model:model-value="item.enable" type="line" size="small" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VueDraggable>
|
</VueDraggable>
|
||||||
<section class="ms-assertion-body-right">
|
<section class="ms-assertion-body-right">
|
||||||
<StatusCodeTab
|
<!-- 响应头 -->
|
||||||
v-if="valueKey === 'statusCode'"
|
|
||||||
:value="codeTabState.statusCode"
|
|
||||||
@change="(val) => handleChange(val, 'statusCode')"
|
|
||||||
/>
|
|
||||||
<ResponseHeaderTab
|
<ResponseHeaderTab
|
||||||
v-if="valueKey === 'responseHeader'"
|
v-if="valueKey === ResponseAssertionType.RESPONSE_HEADER"
|
||||||
:value="codeTabState.responseHeader"
|
v-model:data="getCurrentItemState"
|
||||||
@change="(val) => handleChange(val, 'responseHeader')"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
|
<!-- 状态码 -->
|
||||||
|
<StatusCodeTab
|
||||||
|
v-if="valueKey === ResponseAssertionType.RESPONSE_CODE"
|
||||||
|
v-model:data="getCurrentItemState"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
<!-- 响应体 -->
|
||||||
<ResponseBodyTab
|
<ResponseBodyTab
|
||||||
v-if="valueKey === 'responseBody'"
|
v-if="valueKey === ResponseAssertionType.RESPONSE_BODY"
|
||||||
:value="codeTabState.responseBody"
|
:value="getCurrentItemState"
|
||||||
@change="(val) => handleChange(val, 'responseBody')"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
|
<!-- 响应时间 -->
|
||||||
<ResponseTimeTab
|
<ResponseTimeTab
|
||||||
v-if="valueKey === 'responseTime'"
|
v-if="valueKey === ResponseAssertionType.RESPONSE_TIME"
|
||||||
:value="codeTabState.responseTime"
|
v-model:data="getCurrentItemState"
|
||||||
@="(val) => handleChange(val, 'responseTime')"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
|
<!-- 变量 -->
|
||||||
<VariableTab
|
<VariableTab
|
||||||
v-if="valueKey === 'variable'"
|
v-if="valueKey === ResponseAssertionType.VARIABLE"
|
||||||
:value="codeTabState.variable"
|
v-model:data="getCurrentItemState"
|
||||||
@change="(val) => handleChange(val, 'variable')"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
|
<!-- 脚本 -->
|
||||||
<ScriptTab
|
<ScriptTab
|
||||||
v-if="valueKey === 'script'"
|
v-if="valueKey === ResponseAssertionType.SCRIPT"
|
||||||
:value="codeTabState.script"
|
:value="getCurrentItemState"
|
||||||
@change="(val) => handleChange(val, 'script')"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,6 +98,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineModel } from 'vue';
|
import { defineModel } from 'vue';
|
||||||
|
import { cloneDeep } from 'lodash-es';
|
||||||
import { VueDraggable } from 'vue-draggable-plus';
|
import { VueDraggable } from 'vue-draggable-plus';
|
||||||
|
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
|
@ -107,7 +114,9 @@
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
import { MsAssertionItem, ValueObject } from './type';
|
import { ResponseAssertionType } from '@/enums/apiEnum';
|
||||||
|
|
||||||
|
import { ExecuteAssertion, MsAssertionItem } from './type';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'MsAssertion',
|
name: 'MsAssertion',
|
||||||
|
@ -116,26 +125,28 @@
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
// 当前鼠标所在的key
|
// 当前鼠标所在的key
|
||||||
const focusKey = ref<string>('');
|
const focusKey = ref<string>('');
|
||||||
// 选中的选项
|
// 所有的断言列表参数
|
||||||
const selectItems = defineModel<any[]>('params', { default: [] });
|
const assertions = defineModel<any[]>('params', { default: [] });
|
||||||
// Item点击的key
|
// Item点击的key
|
||||||
const activeKey = ref<string>('');
|
const activeKey = ref<string>(assertions.value[0].id);
|
||||||
// valueKey
|
// 展示的value
|
||||||
const valueKey = computed(() => {
|
const valueKey = computed(() => {
|
||||||
return activeKey.value && selectItems.value.find((item) => item.id === activeKey.value)?.value;
|
return activeKey.value && assertions.value.find((item) => item.id === activeKey.value)?.assertionType;
|
||||||
});
|
});
|
||||||
// 存储当前页面的所有状态
|
|
||||||
const codeTabState = computed({
|
// 计算当前页面的存储的状态
|
||||||
|
const getCurrentItemState = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
return (selectItems.value.find((item) => item.id === activeKey.value)?.valueObj || {}) as ValueObject;
|
return assertions.value.find((item) => item.id === activeKey.value);
|
||||||
},
|
},
|
||||||
set: (val: ValueObject) => {
|
set: (val: ExecuteAssertion) => {
|
||||||
const currentIndex = selectItems.value.findIndex((item) => item.id === val.assertionType);
|
const currentIndex = assertions.value.findIndex((item) => item.id === activeKey.value);
|
||||||
const tmpArr = selectItems.value;
|
const tmpArr = assertions.value;
|
||||||
tmpArr[currentIndex].valueObj = { ...val };
|
tmpArr[currentIndex] = cloneDeep(val);
|
||||||
selectItems.value = tmpArr;
|
assertions.value = tmpArr;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const itemMoreActions: ActionsItem[] = [
|
const itemMoreActions: ActionsItem[] = [
|
||||||
{
|
{
|
||||||
label: 'common.copy',
|
label: 'common.copy',
|
||||||
|
@ -150,62 +161,111 @@
|
||||||
const assertOptionSource = [
|
const assertOptionSource = [
|
||||||
{
|
{
|
||||||
label: t('ms.assertion.statusCode'),
|
label: t('ms.assertion.statusCode'),
|
||||||
value: 'statusCode',
|
value: ResponseAssertionType.RESPONSE_CODE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ms.assertion.responseHeader'),
|
label: t('ms.assertion.responseHeader'),
|
||||||
value: 'responseHeader',
|
value: ResponseAssertionType.RESPONSE_HEADER,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ms.assertion.responseBody'),
|
label: t('ms.assertion.responseBody'),
|
||||||
value: 'responseBody',
|
value: ResponseAssertionType.RESPONSE_BODY,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ms.assertion.responseTime'),
|
label: t('ms.assertion.responseTime'),
|
||||||
value: 'responseTime',
|
value: ResponseAssertionType.RESPONSE_TIME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ms.assertion.param'),
|
label: t('ms.assertion.param'),
|
||||||
value: 'variable',
|
value: ResponseAssertionType.VARIABLE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('ms.assertion.script'),
|
label: t('ms.assertion.script'),
|
||||||
value: 'script',
|
value: ResponseAssertionType.SCRIPT,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// 是否显示主体
|
// 是否显示主体
|
||||||
const showBody = computed(() => {
|
const showBody = computed(() => {
|
||||||
return selectItems.value.length > 0;
|
return assertions.value.length > 0;
|
||||||
});
|
});
|
||||||
// dropdown选择
|
// dropdown选择
|
||||||
const handleSelect = (value: string | number | Record<string, any> | undefined) => {
|
const handleSelect = (value: string | number | Record<string, any> | undefined) => {
|
||||||
|
const id = new Date().getTime().toString();
|
||||||
const tmpObj = {
|
const tmpObj = {
|
||||||
label: assertOptionSource.find((item) => item.value === value)?.label || '',
|
name: assertOptionSource.find((item) => item.value === value)?.label || '',
|
||||||
value: value as string,
|
assertionType: value,
|
||||||
id: new Date().getTime().toString(),
|
id,
|
||||||
|
enable: true,
|
||||||
};
|
};
|
||||||
if (activeKey.value) {
|
|
||||||
const currentIndex = selectItems.value.findIndex((item) => item.id === activeKey.value);
|
switch (value) {
|
||||||
const tmpArr = selectItems.value;
|
// 请求头
|
||||||
tmpArr.splice(currentIndex, 0, tmpObj);
|
case ResponseAssertionType.RESPONSE_HEADER:
|
||||||
selectItems.value = tmpArr;
|
assertions.value.push({
|
||||||
} else {
|
...tmpObj,
|
||||||
selectItems.value.push(tmpObj);
|
assertions: [],
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
// 状态码
|
||||||
|
case ResponseAssertionType.RESPONSE_CODE:
|
||||||
|
assertions.value.push({
|
||||||
|
...tmpObj,
|
||||||
|
condition: '',
|
||||||
|
expectedValue: '',
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.RESPONSE_BODY:
|
||||||
|
assertions.value.push({
|
||||||
|
...tmpObj,
|
||||||
|
assertionBodyType: '',
|
||||||
|
jsonPathAssertion: {
|
||||||
|
assertions: [],
|
||||||
|
},
|
||||||
|
xpathAssertion: {
|
||||||
|
assertions: [],
|
||||||
|
},
|
||||||
|
regexAssertion: {
|
||||||
|
assertions: [],
|
||||||
|
},
|
||||||
|
bodyAssertionDataByType: {},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
// 响应时间
|
||||||
|
case ResponseAssertionType.RESPONSE_TIME:
|
||||||
|
assertions.value.push({
|
||||||
|
...tmpObj,
|
||||||
|
expectedValue: 0,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.VARIABLE:
|
||||||
|
assertions.value.push({
|
||||||
|
...tmpObj,
|
||||||
|
condition: '',
|
||||||
|
expectedValue: '',
|
||||||
|
variableAssertionItems: [],
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.SCRIPT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
activeKey.value = tmpObj.id;
|
activeKey.value = id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMoreActionSelect = (event: ActionsItem, item: MsAssertionItem) => {
|
const handleMoreActionSelect = (event: ActionsItem, item: MsAssertionItem) => {
|
||||||
const currentIndex = selectItems.value.findIndex((tmpItem) => tmpItem.id === item.id);
|
const currentIndex = assertions.value.findIndex((tmpItem) => tmpItem.id === item.id);
|
||||||
if (event.eventTag === 'delete') {
|
if (event.eventTag === 'delete') {
|
||||||
selectItems.value.splice(currentIndex, 1);
|
assertions.value.splice(currentIndex, 1);
|
||||||
activeKey.value = currentIndex > 0 ? selectItems.value[currentIndex - 1].id : '';
|
activeKey.value = currentIndex > 0 ? assertions.value[currentIndex - 1].id : '';
|
||||||
} else {
|
} else {
|
||||||
// copy 当前item
|
// copy 当前item
|
||||||
const tmpObj = { ...selectItems.value[currentIndex], id: new Date().getTime().valueOf().toString() };
|
const tmpObj = { ...assertions.value[currentIndex], id: new Date().getTime().valueOf().toString() };
|
||||||
const tmpArr = selectItems.value;
|
const tmpArr = assertions.value;
|
||||||
tmpArr.splice(currentIndex, 0, tmpObj);
|
tmpArr.splice(currentIndex, 0, tmpObj);
|
||||||
selectItems.value = tmpArr;
|
assertions.value = tmpArr;
|
||||||
activeKey.value = tmpObj.id;
|
activeKey.value = tmpObj.id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -215,9 +275,33 @@
|
||||||
activeKey.value = item.id;
|
activeKey.value = item.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (val: any, key: string) => {
|
const handleChange = (val: any) => {
|
||||||
codeTabState[key] = { ...val, assertionType: key };
|
switch (val.assertionType) {
|
||||||
|
case ResponseAssertionType.RESPONSE_HEADER:
|
||||||
|
getCurrentItemState.value = { ...val };
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.RESPONSE_CODE:
|
||||||
|
getCurrentItemState.value = { ...val };
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.RESPONSE_BODY:
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.RESPONSE_TIME:
|
||||||
|
getCurrentItemState.value = { ...val };
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.VARIABLE:
|
||||||
|
getCurrentItemState.value = { ...val };
|
||||||
|
break;
|
||||||
|
case ResponseAssertionType.SCRIPT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
console.log(getCurrentItemState.value);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import type { ExecuteAssertionItem } from '@/models/apiTest/common';
|
||||||
|
|
||||||
export interface ValueObject {
|
export interface ValueObject {
|
||||||
assertionType: string;
|
assertionType: string;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
@ -8,3 +10,14 @@ export interface MsAssertionItem {
|
||||||
value: string;
|
value: string;
|
||||||
valueObj: ValueObject;
|
valueObj: ValueObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ExecuteAssertion {
|
||||||
|
assertionType: string;
|
||||||
|
enable: boolean;
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
assertions: ExecuteAssertionItem[];
|
||||||
|
expectedValue: any;
|
||||||
|
condition: string;
|
||||||
|
variableAssertionItems: ExecuteAssertionItem[];
|
||||||
|
}
|
||||||
|
|
|
@ -264,17 +264,22 @@
|
||||||
@change="handleTypeCheckingColChange(false)"
|
@change="handleTypeCheckingColChange(false)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #responseHeader="{ record, columnConfig, rowIndex }">
|
<!-- 响应头 -->
|
||||||
<a-select v-model="record.responseHeader" class="param-input" size="mini" @change="() => addTableLine(rowIndex)">
|
<template #header="{ record, columnConfig, rowIndex }">
|
||||||
|
<a-select v-model="record.header" class="param-input" size="mini" @change="() => addTableLine(rowIndex)">
|
||||||
<a-option v-for="item in columnConfig.options" :key="item.value">{{ t(item.label) }}</a-option>
|
<a-option v-for="item in columnConfig.options" :key="item.value">{{ t(item.label) }}</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
<template #matchCondition="{ record, columnConfig }">
|
<!-- 匹配条件 -->
|
||||||
|
<template #condition="{ record, columnConfig }">
|
||||||
<a-select v-model="record.condition" size="mini" class="param-input">
|
<a-select v-model="record.condition" size="mini" class="param-input">
|
||||||
<a-option v-for="item in columnConfig.options" :key="item.value">{{ t(item.label) }}</a-option>
|
<a-option v-for="item in columnConfig.options" :key="item.value" :value="item.value">{{
|
||||||
|
t(item.label)
|
||||||
|
}}</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
<template #matchValue="{ record, rowIndex, columnConfig }">
|
<!-- 匹配值 -->
|
||||||
|
<template #expectedValue="{ record, rowIndex, columnConfig }">
|
||||||
<a-tooltip
|
<a-tooltip
|
||||||
v-if="columnConfig.hasRequired"
|
v-if="columnConfig.hasRequired"
|
||||||
:content="t(record.required ? 'apiTestDebug.paramRequired' : 'apiTestDebug.paramNotRequired')"
|
:content="t(record.required ? 'apiTestDebug.paramRequired' : 'apiTestDebug.paramNotRequired')"
|
||||||
|
@ -291,7 +296,7 @@
|
||||||
<div>*</div>
|
<div>*</div>
|
||||||
</MsButton>
|
</MsButton>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-input v-model="record.matchValue" size="mini" class="param-input" />
|
<a-input v-model="record.expectedValue" size="mini" class="param-input" />
|
||||||
</template>
|
</template>
|
||||||
<template #project="{ record, rowIndex }">
|
<template #project="{ record, rowIndex }">
|
||||||
<a-select
|
<a-select
|
||||||
|
|
Loading…
Reference in New Issue