From 1a13f39a968f41aaf28a1d799b53c1f906c6a81d Mon Sep 17 00:00:00 2001 From: baiqi Date: Mon, 22 Apr 2024 21:01:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=85=A8=E5=B1=80):=20bug=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ms-assertion/comp/ResponseBodyTab.vue | 77 +++---------------- .../business/ms-assertion/index.vue | 6 +- .../pure/ms-jsonpath-picker/xpath.vue | 55 ++++++++----- frontend/src/models/apiTest/scenario.ts | 2 + .../api-test/components/condition/content.vue | 2 +- .../api-test/components/condition/index.vue | 29 ++++--- .../src/views/api-test/components/config.ts | 54 +++++++++++++ .../components/fastExtraction/index.vue | 5 +- .../views/api-test/components/paramTable.vue | 18 ++++- .../components/requestAndResponse.vue | 34 ++++---- .../components/requestComposition/index.vue | 45 +---------- .../requestComposition/postcondition.vue | 3 + .../requestComposition/precondition.vue | 3 + .../src/views/api-test/components/utils.ts | 69 ++++++++++++++++- .../components/common/customApiDrawer.vue | 30 +++----- .../components/common/customCaseDrawer.vue | 31 +++----- .../api-test/scenario/components/prePost.vue | 22 +++++- .../scenario/components/step/stepTree.vue | 6 +- .../src/views/api-test/scenario/index.vue | 57 ++++++++++---- .../views/api-test/scenario/locale/en-US.ts | 2 + .../views/api-test/scenario/locale/zh-CN.ts | 2 + 21 files changed, 319 insertions(+), 233 deletions(-) diff --git a/frontend/src/components/business/ms-assertion/comp/ResponseBodyTab.vue b/frontend/src/components/business/ms-assertion/comp/ResponseBodyTab.vue index 2318086b14..d59fc1808d 100644 --- a/frontend/src/components/business/ms-assertion/comp/ResponseBodyTab.vue +++ b/frontend/src/components/business/ms-assertion/comp/ResponseBodyTab.vue @@ -124,7 +124,7 @@ :selectable="true" :columns="xPathColumns" :scroll="{ minWidth: '700px' }" - :default-param-item="xPathDefaultParamItem" + :default-param-item="defaultAssertParamsItem" @change="(data:any[],isInit?: boolean) => handleChange(data, ResponseBodyAssertionType.XPATH,isInit)" @more-action-select="(e,r)=> handleExtractParamMoreActionSelect(e,r as ExpressionConfig)" > @@ -363,7 +363,7 @@ import { TableColumnData, TableData } from '@arco-design/web-vue'; import { cloneDeep } from 'lodash-es'; - import { EQUAL, statusCodeOptions } from '@/components/pure/ms-advance-filter'; + import { statusCodeOptions } from '@/components/pure/ms-advance-filter'; import { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import { TableOperationColumn } from '@/components/business/ms-user-group-comp/authTable.vue'; import fastExtraction from '@/views/api-test/components/fastExtraction/index.vue'; @@ -387,15 +387,14 @@ RegexExtract, XPathExtract, } from '@/models/apiTest/common'; + import { RequestExtractExpressionEnum, ResponseBodyAssertionType } from '@/enums/apiEnum'; + import { - RequestExtractEnvType, - RequestExtractExpressionEnum, - RequestExtractExpressionRuleType, - RequestExtractResultMatchingRule, - RequestExtractScope, - ResponseBodyAssertionType, - ResponseBodyXPathAssertionFormat, - } from '@/enums/apiEnum'; + defaultAssertParamsItem, + defaultExtractParamItem, + jsonPathDefaultParamItem, + regexDefaultParamItem, + } from '@/views/api-test/components/config'; const { t } = useI18n(); @@ -445,20 +444,6 @@ // const disabledExpressionSuffix = ref(false); export type ExpressionConfig = (RegexExtract | JSONPathExtract | XPathExtract) & Record; - const defaultExtractParamItem: ExpressionConfig = { - enable: true, - variableName: '', - variableType: RequestExtractEnvType.TEMPORARY, - extractScope: RequestExtractScope.BODY, - expression: '', - extractType: RequestExtractExpressionEnum.JSON_PATH, - expressionMatchingRule: RequestExtractExpressionRuleType.EXPRESSION, - resultMatchingRule: RequestExtractResultMatchingRule.RANDOM, - resultMatchingRuleNum: 1, - responseFormat: ResponseBodyXPathAssertionFormat.XML, - moreSettingPopoverVisible: false, - }; - const activeRecord = ref({ ...defaultExtractParamItem }); // 用于暂存当前操作的提取参数表格项 const responseRadios = [ @@ -506,50 +491,6 @@ }, ]; - // json默认值 - const jsonPathDefaultParamItem = { - enable: true, - variableName: '', - variableType: RequestExtractEnvType.TEMPORARY, - extractScope: RequestExtractScope.BODY, - expression: '', - condition: EQUAL.value, - extractType: RequestExtractExpressionEnum.JSON_PATH, - expressionMatchingRule: RequestExtractExpressionRuleType.EXPRESSION, - resultMatchingRule: RequestExtractResultMatchingRule.RANDOM, - resultMatchingRuleNum: 1, - responseFormat: ResponseBodyXPathAssertionFormat.XML, - moreSettingPopoverVisible: false, - }; - // xpath默认值 - const xPathDefaultParamItem = { - expression: '', - enable: true, - valid: true, - variableType: RequestExtractEnvType.TEMPORARY, - extractScope: RequestExtractScope.BODY, - extractType: RequestExtractExpressionEnum.X_PATH, - expressionMatchingRule: RequestExtractExpressionRuleType.EXPRESSION, - resultMatchingRule: RequestExtractResultMatchingRule.RANDOM, - resultMatchingRuleNum: 1, - responseFormat: ResponseBodyXPathAssertionFormat.XML, - moreSettingPopoverVisible: false, - }; - // xpath默认值 - const regexDefaultParamItem = { - expression: '', - enable: true, - valid: true, - variableType: RequestExtractEnvType.TEMPORARY, - extractScope: RequestExtractScope.BODY, - extractType: RequestExtractExpressionEnum.REGEX, - expressionMatchingRule: RequestExtractExpressionRuleType.EXPRESSION, - resultMatchingRule: RequestExtractResultMatchingRule.RANDOM, - resultMatchingRuleNum: 1, - responseFormat: ResponseBodyXPathAssertionFormat.XML, - moreSettingPopoverVisible: false, - }; - const handleChange = (data: any[], type: string, isInit?: boolean) => { switch (type) { case ResponseBodyAssertionType.JSON_PATH: diff --git a/frontend/src/components/business/ms-assertion/index.vue b/frontend/src/components/business/ms-assertion/index.vue index bf4f48ba8b..2194f373a0 100644 --- a/frontend/src/components/business/ms-assertion/index.vue +++ b/frontend/src/components/business/ms-assertion/index.vue @@ -9,9 +9,9 @@
diff --git a/frontend/src/components/pure/ms-jsonpath-picker/xpath.vue b/frontend/src/components/pure/ms-jsonpath-picker/xpath.vue index 44dcb9f6c7..74075157f5 100644 --- a/frontend/src/components/pure/ms-jsonpath-picker/xpath.vue +++ b/frontend/src/components/pure/ms-jsonpath-picker/xpath.vue @@ -115,15 +115,26 @@ /** * 替换文档 * @param beautifyDoc 格式化后的文档 + * @param isHtml 是否是html */ - function replaceDoc(beautifyDoc: string) { - // 先将 HTML 字符串格式化,然后解析转换并给每个开始标签加上复制 icon - flattenedXml.value = beautifyDoc + function replaceDoc(beautifyDoc: string, isHtml = false) { + // 先将 XML/HTML 字符串格式化,然后解析转换并给每个开始标签加上复制 icon + let resultArr: XpathNode[] = []; + const tempStr = beautifyDoc .replace(//g, '>') - .replace(/(<([^/][^&]*?)>)/g, '$1📋') - .split(/\r?\n/) - .map((e) => ({ content: e, xpath: '' })); + .replace(/(<([^/][^&]*?)>)/g, '$1📋'); + if (isHtml) { + resultArr = HtmlBeautify( + tempStr.replace(/(\S)(?=<)/gs, '$1\n'), // html 标签换行 + { ocd: true } + ) + .split(/\r?\n/) + .map((e) => ({ content: e, xpath: '' })); + } else { + resultArr = tempStr.split(/\r?\n/).map((e) => ({ content: e, xpath: '' })); + } + flattenedXml.value = resultArr; } /** @@ -142,8 +153,9 @@ isValidXml.value = true; parsedXml.value = xmlDoc; const beautifyDoc = HtmlBeautify(props.xmlString, { ocd: true }); - replaceDoc(beautifyDoc); + replaceDoc(beautifyDoc, true); // 解析真实 HTML 并将其扁平化,得到每个节点的 xpath + tempXmls.value = []; flattenHtml(xmlDoc.documentElement, ''); // 将扁平化后的 XML/HTML 字符串中的每个节点的 xpath 替换为真实的 xpath flattenedXml.value = flattenedXml.value @@ -157,7 +169,7 @@ xpath, }; } - return false; + return e.content.includes('</') ? e : false; }) .filter(Boolean) as any[]; emit('init', 'html'); @@ -185,20 +197,23 @@ const beautifyDoc = new XmlBeautify().beautify(props.xmlString); replaceDoc(beautifyDoc); // 解析真实 XML 并将其扁平化,得到每个节点的 xpath + tempXmls.value = []; flattenXml(xmlDoc.documentElement, ''); // 将扁平化后的 XML 字符串中的每个节点的 xpath 替换为真实的 xpath - flattenedXml.value = flattenedXml.value.map((e) => { - const targetNodeIndex = tempXmls.value.findIndex((txt) => e.content.includes(`<${txt.content}`)); - if (targetNodeIndex >= 0) { - const { xpath } = tempXmls.value[targetNodeIndex]; - tempXmls.value.splice(targetNodeIndex, 1); // 匹配成功后,将匹配到的节点从 tempXmls 中删除,避免重复匹配 - return { - ...e, - xpath, - }; - } - return e; - }); + flattenedXml.value = flattenedXml.value + .map((e) => { + const targetNodeIndex = tempXmls.value.findIndex((txt) => e.content.includes(`<${txt.content}`)); + if (targetNodeIndex >= 0) { + const { xpath } = tempXmls.value[targetNodeIndex]; + tempXmls.value.splice(targetNodeIndex, 1); // 匹配成功后,将匹配到的节点从 tempXmls 中删除,避免重复匹配 + return { + ...e, + xpath, + }; + } + return false; + }) + .filter(Boolean) as any[]; emit('init', 'xml'); } catch (error) { // eslint-disable-next-line no-console diff --git a/frontend/src/models/apiTest/scenario.ts b/frontend/src/models/apiTest/scenario.ts index c834587227..c83c49e94b 100644 --- a/frontend/src/models/apiTest/scenario.ts +++ b/frontend/src/models/apiTest/scenario.ts @@ -78,6 +78,8 @@ export interface ApiScenarioTableItem { deleteUser: string; deleteTime: number; deleted: boolean; + environmentId: string; + environmentName: string; createUserName: string; updateUserName: string; deleteUserName: string; diff --git a/frontend/src/views/api-test/components/condition/content.vue b/frontend/src/views/api-test/components/condition/content.vue index c108aca387..307d125610 100644 --- a/frontend/src/views/api-test/components/condition/content.vue +++ b/frontend/src/views/api-test/components/condition/content.vue @@ -276,7 +276,7 @@