fix(接口测试): 【接口测试】github#26757

--bug=1030567 --user=白奇 【接口测试】github#26757,【特定场景脚本必现】浏览器访问接口自动化-编辑接口场景页面,浏览器报错,safari浏览器无法显示场景列表,谷歌浏览器样式存在穿透同时导致上下滚动页面到某处后页面自动上下胡乱滚动 https://www.tapd.cn/55049933/s/1424019
This commit is contained in:
baiqi 2023-10-10 10:50:47 +08:00 committed by fit2-zhao
parent 657b4decf7
commit e2476b7209
4 changed files with 171 additions and 119 deletions

View File

@ -107,7 +107,7 @@ import BatchAddParameter from '../basis/BatchAddParameter';
import Convert from '@/business/commons/json-schema/convert/convert'; import Convert from '@/business/commons/json-schema/convert/convert';
import { getApiParamsConfigFields } from 'metersphere-frontend/src/utils/custom_field'; import { getApiParamsConfigFields } from 'metersphere-frontend/src/utils/custom_field';
import ApiParamsConfig from '@/business/definition/components/request/components/ApiParamsConfig'; import ApiParamsConfig from '@/business/definition/components/request/components/ApiParamsConfig';
import { parse } from 'lossless-json' import { parse } from 'lossless-json';
import CustomNum from '../../../commons/json-schema/convert/customNum'; import CustomNum from '../../../commons/json-schema/convert/customNum';
export default { export default {
@ -177,18 +177,8 @@ export default {
// 300ms 使 // 300ms 使
if (this.body.format === 'JSON-SCHEMA') { if (this.body.format === 'JSON-SCHEMA') {
this.$refs.jsonCodeEdit?.$el.querySelector('.ace_text-input')?.focus(); this.$refs.jsonCodeEdit?.$el.querySelector('.ace_text-input')?.focus();
this.$refs.jsonCodeEdit?.$parent?.$parent?.$parent?.$parent?.$parent.$el.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'center',
});
} else if (this.codeEditActive) { } else if (this.codeEditActive) {
this.$refs.codeEdit?.$el.querySelector('.ace_text-input')?.focus(); this.$refs.codeEdit?.$el.querySelector('.ace_text-input')?.focus();
this.$refs.codeEdit?.$parent?.$parent?.$parent?.$parent?.$parent?.$el.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'center',
});
} }
}, 300); }, 300);
}, },
@ -287,7 +277,7 @@ export default {
if (this.body.format === 'JSON-SCHEMA') { if (this.body.format === 'JSON-SCHEMA') {
if (this.body.raw) { if (this.body.raw) {
try { try {
const jsonObj = parse(this.body.raw) const jsonObj = parse(this.body.raw);
this.body.jsonSchema = MsConvert.format(jsonObj); this.body.jsonSchema = MsConvert.format(jsonObj);
} catch (e) { } catch (e) {
this.body.format = 'JSON'; this.body.format = 'JSON';

View File

@ -2,7 +2,8 @@
<div class="text-container" v-if="responseResult"> <div class="text-container" v-if="responseResult">
<el-tabs v-model="activeName" v-show="isActive"> <el-tabs v-model="activeName" v-show="isActive">
<el-tab-pane :label="$t('api_test.definition.request.response_body')" name="body" class="pane"> <el-tab-pane :label="$t('api_test.definition.request.response_body')" name="body" class="pane">
<ms-sql-result-table v-if="isSqlType && activeName === 'body' && !responseResult.contentType" <ms-sql-result-table
v-if="isSqlType && activeName === 'body' && !responseResult.contentType"
:body="responseResult.body" /> :body="responseResult.body" />
<ms-code-edit <ms-code-edit
v-if="!isSqlType && isMsCodeEditShow && activeName === 'body' && !isPicture" v-if="!isSqlType && isMsCodeEditShow && activeName === 'body' && !isPicture"
@ -14,10 +15,9 @@
ref="codeEdit" /> ref="codeEdit" />
<el-row v-if="isPicture && activeName === 'body'"> <el-row v-if="isPicture && activeName === 'body'">
<el-col :span="24"> <el-col :span="24">
<el-image :src="srcUrl" fit="contain" style="width: 100%;height: 100%;"></el-image> <el-image :src="srcUrl" fit="contain" style="width: 100%; height: 100%"></el-image>
</el-col> </el-col>
</el-row> </el-row>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane"> <el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane">
@ -90,7 +90,7 @@ import MsCodeEdit from '../MsCodeEdit';
import MsDropdown from '../../../../business/commons/MsDropdown'; import MsDropdown from '../../../../business/commons/MsDropdown';
import { BODY_FORMAT } from '../../model/ApiTestModel'; import { BODY_FORMAT } from '../../model/ApiTestModel';
import MsSqlResultTable from './SqlResultTable'; import MsSqlResultTable from './SqlResultTable';
import {downloadByURL} from "fit2cloud-ui/src/tools/utils"; import { downloadByURL } from 'fit2cloud-ui/src/tools/utils';
export default { export default {
name: 'MsResponseResult', name: 'MsResponseResult',
@ -122,7 +122,16 @@ export default {
mode: BODY_FORMAT.TEXT, mode: BODY_FORMAT.TEXT,
isMsCodeEditShow: true, isMsCodeEditShow: true,
reqMessages: '', reqMessages: '',
contentType: ['image/png', 'image/jpeg', 'image/gif', 'image/bmp', 'image/webp', 'image/svg+xml', 'image/apng', 'image/avif'], contentType: [
'image/png',
'image/jpeg',
'image/gif',
'image/bmp',
'image/webp',
'image/svg+xml',
'image/apng',
'image/avif',
],
srcUrl: '', srcUrl: '',
}; };
}, },
@ -137,11 +146,6 @@ export default {
setTimeout(() => { setTimeout(() => {
// 300ms 使 // 300ms 使
this.$refs.codeEdit?.$el.querySelector('.ace_text-input')?.focus(); this.$refs.codeEdit?.$el.querySelector('.ace_text-input')?.focus();
this.$refs.codeEdit?.$parent?.$parent?.$parent?.$parent?.$parent?.$el.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center',
});
}, 300); }, 300);
}, },
immediate: true, immediate: true,
@ -156,7 +160,7 @@ export default {
}, },
showPicture() { showPicture() {
if (this.responseResult.contentType && this.contentType.includes(this.responseResult.contentType)) { if (this.responseResult.contentType && this.contentType.includes(this.responseResult.contentType)) {
this.modes.push('picture') this.modes.push('picture');
this.srcUrl = 'data:' + this.responseResult.contentType + ';base64,' + this.responseResult.imageUrl; this.srcUrl = 'data:' + this.responseResult.contentType + ';base64,' + this.responseResult.imageUrl;
} }
}, },
@ -239,7 +243,11 @@ export default {
return this.response && this.response.responseResult ? this.response.responseResult : {}; return this.response && this.response.responseResult ? this.response.responseResult : {};
}, },
isPicture() { isPicture() {
return this.responseResult.contentType && this.contentType.includes(this.responseResult.contentType) && this.mode === 'picture'; return (
this.responseResult.contentType &&
this.contentType.includes(this.responseResult.contentType) &&
this.mode === 'picture'
);
}, },
}, },
}; };

View File

@ -83,7 +83,7 @@ export default {
this.data = {}; this.data = {};
try { try {
let stringedJSON = objStr.replace( let stringedJSON = objStr.replace(
/(?<=[:\[,])\s*(-?\d+(\.\d+)?)(?=\s*([,\]}]))/g, /(?:[:\[,])\s*(-?\d+(\.\d+)?)(?=\s*([,\]}]))/g,
'"$1"' '"$1"'
); );
let param; let param;

View File

@ -1,8 +1,15 @@
<template> <template>
<div class="text-container" v-if="responseResult"> <div class="text-container" v-if="responseResult">
<el-tabs v-model="activeName" v-show="isActive" class="response-result"> <el-tabs v-model="activeName" v-show="isActive" class="response-result">
<el-tab-pane :label="$t('api_test.definition.request.response_body')" name="body" class="pane"> <el-tab-pane
<ms-sql-result-table v-if="isSqlType && activeName === 'body'" :body="responseResult.body"/> :label="$t('api_test.definition.request.response_body')"
name="body"
class="pane"
>
<ms-sql-result-table
v-if="isSqlType && activeName === 'body'"
:body="responseResult.body"
/>
<ms-code-edit <ms-code-edit
v-if="!isSqlType && isMsCodeEditShow && activeName === 'body'" v-if="!isSqlType && isMsCodeEditShow && activeName === 'body'"
:mode="mode" :mode="mode"
@ -10,58 +17,98 @@
:modes="modes" :modes="modes"
:data.sync="responseResult.body" :data.sync="responseResult.body"
height="250px" height="250px"
ref="codeEdit"/> ref="codeEdit"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane"> <el-tab-pane
:label="$t('api_test.definition.request.response_header')"
name="headers"
class="pane"
>
<ms-code-edit <ms-code-edit
:mode="'text'" :mode="'text'"
:read-only="true" :read-only="true"
:data.sync="responseResult.headers" :data.sync="responseResult.headers"
ref="codeEdit" ref="codeEdit"
v-if="activeName === 'headers'"/> v-if="activeName === 'headers'"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="responseResult.console" :label="$t('api_test.definition.request.console')" name="console" <el-tab-pane
class="pane"> v-if="responseResult.console"
:label="$t('api_test.definition.request.console')"
name="console"
class="pane"
>
<ms-code-edit <ms-code-edit
:mode="'text'" :mode="'text'"
:read-only="true" :read-only="true"
:data.sync="responseResult.console" :data.sync="responseResult.console"
ref="codeEdit" ref="codeEdit"
v-if="activeName === 'console'"/> v-if="activeName === 'console'"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_report.assertions')" name="assertions" class="pane assertions"> <el-tab-pane
<ms-assertion-results :assertions="responseResult.assertions" v-if="activeName === 'assertions'"/> :label="$t('api_report.assertions')"
name="assertions"
class="pane assertions"
>
<ms-assertion-results
:assertions="responseResult.assertions"
v-if="activeName === 'assertions'"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_test.request.extract.label')" name="label" class="pane"> <el-tab-pane
:label="$t('api_test.request.extract.label')"
name="label"
class="pane"
>
<ms-code-edit <ms-code-edit
:mode="'text'" :mode="'text'"
:read-only="true" :read-only="true"
:data.sync="responseResult.vars" :data.sync="responseResult.vars"
v-if="activeName === 'label'" v-if="activeName === 'label'"
ref="codeEdit"/> ref="codeEdit"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('api_report.request_body')" name="request_body" class="pane"> <el-tab-pane
:label="$t('api_report.request_body')"
name="request_body"
class="pane"
>
<ms-code-edit <ms-code-edit
:mode="'text'" :mode="'text'"
:read-only="true" :read-only="true"
:data.sync="reqMessages" :data.sync="reqMessages"
v-if="activeName === 'request_body'" v-if="activeName === 'request_body'"
ref="codeEdit"/> ref="codeEdit"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="activeName == 'body'" :disabled="true" name="mode" class="pane cookie"> <el-tab-pane
v-if="activeName == 'body'"
:disabled="true"
name="mode"
class="pane cookie"
>
<template v-slot:label> <template v-slot:label>
<ms-dropdown <ms-dropdown
v-if="currentProtocol === 'SQL'" v-if="currentProtocol === 'SQL'"
:commands="sqlModes" :commands="sqlModes"
:default-command="mode" :default-command="mode"
@command="sqlModeChange"/> @command="sqlModeChange"
<ms-dropdown v-else :commands="modes" :default-command="mode" @command="modeChange" ref="modeDropdown"/> />
<ms-dropdown
v-else
:commands="modes"
:default-command="mode"
@command="modeChange"
ref="modeDropdown"
/>
</template> </template>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@ -69,13 +116,13 @@
</template> </template>
<script> <script>
import MsAssertionResults from './AssertionResults'; import MsAssertionResults from "./AssertionResults";
import MsCodeEdit from './MsCodeEdit'; import MsCodeEdit from "./MsCodeEdit";
import MsDropdown from './MsDropdown'; import MsDropdown from "./MsDropdown";
import MsSqlResultTable from './SqlResultTable'; import MsSqlResultTable from "./SqlResultTable";
export default { export default {
name: 'MsResponseResult', name: "MsResponseResult",
components: { components: {
MsDropdown, MsDropdown,
@ -92,18 +139,18 @@ export default {
data() { data() {
return { return {
isActive: true, isActive: true,
activeName: 'body', activeName: "body",
modes: ['text', 'json', 'xml', 'html'], modes: ["text", "json", "xml", "html"],
sqlModes: ['text', 'table'], sqlModes: ["text", "table"],
bodyFormat: { bodyFormat: {
TEXT: 'text', TEXT: "text",
JSON: 'json', JSON: "json",
XML: 'xml', XML: "xml",
HTML: 'html', HTML: "html",
}, },
mode: 'text', mode: "text",
isMsCodeEditShow: true, isMsCodeEditShow: true,
reqMessages: '', reqMessages: "",
}; };
}, },
watch: { watch: {
@ -115,12 +162,7 @@ export default {
handler() { handler() {
setTimeout(() => { setTimeout(() => {
// 300ms 使 // 300ms 使
this.$refs.codeEdit?.$el.querySelector('.ace_text-input')?.focus(); this.$refs.codeEdit?.$el.querySelector(".ace_text-input")?.focus();
this.$refs.codeEdit?.$parent?.$parent?.$parent?.$parent?.$parent?.$el.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center',
});
}, 300); }, 300);
}, },
immediate: true, immediate: true,
@ -138,7 +180,9 @@ export default {
this.response && this.response &&
this.response.responseResult && this.response.responseResult &&
this.response.responseResult.headers && this.response.responseResult.headers &&
this.response.responseResult.headers.indexOf('Content-Type: application/json') > 0 this.response.responseResult.headers.indexOf(
"Content-Type: application/json"
) > 0
) { ) {
this.mode = this.bodyFormat.JSON; this.mode = this.bodyFormat.JSON;
this.$nextTick(() => { this.$nextTick(() => {
@ -158,35 +202,43 @@ export default {
setReqMessage() { setReqMessage() {
if (this.response) { if (this.response) {
if (!this.response.url) { if (!this.response.url) {
this.response.url = ''; this.response.url = "";
} }
if (!this.response.headers) { if (!this.response.headers) {
this.response.headers = ''; this.response.headers = "";
} }
if (!this.response.cookies) { if (!this.response.cookies) {
this.response.cookies = ''; this.response.cookies = "";
} }
if (!this.response.body) { if (!this.response.body) {
this.response.body = ''; this.response.body = "";
} }
if (!this.response.responseResult) { if (!this.response.responseResult) {
this.response.responseResult = {}; this.response.responseResult = {};
} }
if (!this.response.responseResult.vars) { if (!this.response.responseResult.vars) {
this.response.responseResult.vars = ''; this.response.responseResult.vars = "";
} }
this.reqMessages = ''; this.reqMessages = "";
if (this.response.url) { if (this.response.url) {
this.reqMessages += this.$t('api_test.request.address') + ':\n' + this.response.url + '\n'; this.reqMessages +=
this.$t("api_test.request.address") +
":\n" +
this.response.url +
"\n";
} }
if (this.response.headers) { if (this.response.headers) {
this.reqMessages += this.$t('api_test.scenario.headers') + ':\n' + this.response.headers + '\n'; this.reqMessages +=
this.$t("api_test.scenario.headers") +
":\n" +
this.response.headers +
"\n";
} }
if (this.response.cookies) { if (this.response.cookies) {
this.reqMessages += 'Cookie:' + this.response.cookies + '\n'; this.reqMessages += "Cookie:" + this.response.cookies + "\n";
} }
this.reqMessages += 'Body:' + '\n' + this.response.body; this.reqMessages += "Body:" + "\n" + this.response.body;
if (this.mode === this.bodyFormat.JSON) { if (this.mode === this.bodyFormat.JSON) {
this.msCodeReload(); this.msCodeReload();
} }
@ -200,15 +252,17 @@ export default {
computed: { computed: {
isSqlType() { isSqlType() {
return ( return (
this.currentProtocol === 'SQL' && this.currentProtocol === "SQL" &&
this.response && this.response &&
this.response.responseResult && this.response.responseResult &&
this.response.responseResult.responseCode === '200' && this.response.responseResult.responseCode === "200" &&
this.mode === 'table' this.mode === "table"
); );
}, },
responseResult() { responseResult() {
return this.response && this.response.responseResult ? this.response.responseResult : {}; return this.response && this.response.responseResult
? this.response.responseResult
: {};
}, },
}, },
}; };