chore: collection runner enhancements and ui clean up (#4564)
Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
@@ -1215,6 +1215,7 @@
|
|||||||
"include_active_environment": "Include active environment:",
|
"include_active_environment": "Include active environment:",
|
||||||
"cli": "CLI",
|
"cli": "CLI",
|
||||||
"delay": "Delay",
|
"delay": "Delay",
|
||||||
|
"negative_delay": "Delay cannot be negative",
|
||||||
"ui": "Runner",
|
"ui": "Runner",
|
||||||
"running_collection": "Running collection",
|
"running_collection": "Running collection",
|
||||||
"run_config": "Run Configuration",
|
"run_config": "Run Configuration",
|
||||||
@@ -1228,7 +1229,9 @@
|
|||||||
"cli_command_generation_description_cloud": "Copy the below command and run it from the CLI. Please specify a personal access token.",
|
"cli_command_generation_description_cloud": "Copy the below command and run it from the CLI. Please specify a personal access token.",
|
||||||
"cli_command_generation_description_sh": "Copy the below command and run it from the CLI. Please specify a personal access token and verify the generated SH instance server URL.",
|
"cli_command_generation_description_sh": "Copy the below command and run it from the CLI. Please specify a personal access token and verify the generated SH instance server URL.",
|
||||||
"cli_command_generation_description_sh_with_server_url_placeholder": "Copy the below command and run it from the CLI. Please specify a personal access token and the SH instance server URL.",
|
"cli_command_generation_description_sh_with_server_url_placeholder": "Copy the below command and run it from the CLI. Please specify a personal access token and the SH instance server URL.",
|
||||||
"run_collection": "Run collection"
|
"run_collection": "Run collection",
|
||||||
|
"no_passed_tests": "No tests passed",
|
||||||
|
"no_failed_tests": "No tests failed"
|
||||||
},
|
},
|
||||||
"ai_experiments": {
|
"ai_experiments": {
|
||||||
"generate_request_name": "Generate Request Name Using AI",
|
"generate_request_name": "Generate Request Name Using AI",
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ declare module 'vue' {
|
|||||||
HttpAuthorizationNTLM: typeof import('./components/http/authorization/NTLM.vue')['default']
|
HttpAuthorizationNTLM: typeof import('./components/http/authorization/NTLM.vue')['default']
|
||||||
HttpAuthorizationOAuth2: typeof import('./components/http/authorization/OAuth2.vue')['default']
|
HttpAuthorizationOAuth2: typeof import('./components/http/authorization/OAuth2.vue')['default']
|
||||||
HttpBody: typeof import('./components/http/Body.vue')['default']
|
HttpBody: typeof import('./components/http/Body.vue')['default']
|
||||||
|
HttpBodyBinary: typeof import('./components/http/BodyBinary.vue')['default']
|
||||||
HttpBodyParameters: typeof import('./components/http/BodyParameters.vue')['default']
|
HttpBodyParameters: typeof import('./components/http/BodyParameters.vue')['default']
|
||||||
HttpCodegen: typeof import('./components/http/Codegen.vue')['default']
|
HttpCodegen: typeof import('./components/http/Codegen.vue')['default']
|
||||||
HttpCodegenModal: typeof import('./components/http/CodegenModal.vue')['default']
|
HttpCodegenModal: typeof import('./components/http/CodegenModal.vue')['default']
|
||||||
@@ -225,6 +226,7 @@ declare module 'vue' {
|
|||||||
ImportExportImportExportSourcesList: typeof import('./components/importExport/ImportExportSourcesList.vue')['default']
|
ImportExportImportExportSourcesList: typeof import('./components/importExport/ImportExportSourcesList.vue')['default']
|
||||||
ImportExportImportExportStepsAllCollectionImport: typeof import('./components/importExport/ImportExportSteps/AllCollectionImport.vue')['default']
|
ImportExportImportExportStepsAllCollectionImport: typeof import('./components/importExport/ImportExportSteps/AllCollectionImport.vue')['default']
|
||||||
ImportExportImportExportStepsFileImport: typeof import('./components/importExport/ImportExportSteps/FileImport.vue')['default']
|
ImportExportImportExportStepsFileImport: typeof import('./components/importExport/ImportExportSteps/FileImport.vue')['default']
|
||||||
|
ImportExportImportExportStepsImportSummary: typeof import('./components/importExport/ImportExportSteps/ImportSummary.vue')['default']
|
||||||
ImportExportImportExportStepsMyCollectionImport: typeof import('./components/importExport/ImportExportSteps/MyCollectionImport.vue')['default']
|
ImportExportImportExportStepsMyCollectionImport: typeof import('./components/importExport/ImportExportSteps/MyCollectionImport.vue')['default']
|
||||||
ImportExportImportExportStepsUrlImport: typeof import('./components/importExport/ImportExportSteps/UrlImport.vue')['default']
|
ImportExportImportExportStepsUrlImport: typeof import('./components/importExport/ImportExportSteps/UrlImport.vue')['default']
|
||||||
InterceptorsAgentModalNativeCACertificates: typeof import('./components/interceptors/agent/ModalNativeCACertificates.vue')['default']
|
InterceptorsAgentModalNativeCACertificates: typeof import('./components/interceptors/agent/ModalNativeCACertificates.vue')['default']
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
class="w-full rounded px-4 py-3 transition cursor-pointer focus:outline-none hover:active hover:bg-primaryLight hover:text-secondaryDark"
|
class="w-full rounded px-4 py-3 transition cursor-pointer focus:outline-none hover:active hover:bg-primaryLight hover:text-secondaryDark"
|
||||||
@click="selectRequest()"
|
@click="selectRequest()"
|
||||||
>
|
>
|
||||||
<div class="flex gap-4 mb-1">
|
<div class="flex gap-4 mb-1 items-center">
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center truncate pointer-events-none"
|
class="flex items-center justify-center truncate pointer-events-none"
|
||||||
:style="{ color: requestLabelColor }"
|
:style="{ color: requestLabelColor }"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
v-if="request.response?.statusCode"
|
v-if="request.response?.statusCode"
|
||||||
:class="[
|
:class="[
|
||||||
statusCategory.className,
|
statusCategory.className,
|
||||||
'outlined text-xs rounded-md px-2 flex items-center',
|
'outlined text-[10px] rounded px-2 flex items-center',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ `${request.response?.statusCode}` }}
|
{{ `${request.response?.statusCode}` }}
|
||||||
|
|||||||
@@ -31,13 +31,11 @@
|
|||||||
<HoppButtonPrimary
|
<HoppButtonPrimary
|
||||||
v-if="showResult && tab.document.status === 'running'"
|
v-if="showResult && tab.document.status === 'running'"
|
||||||
:label="t('test.stop')"
|
:label="t('test.stop')"
|
||||||
class="w-32"
|
|
||||||
@click="stopTests()"
|
@click="stopTests()"
|
||||||
/>
|
/>
|
||||||
<HoppButtonPrimary
|
<HoppButtonPrimary
|
||||||
v-else
|
v-else
|
||||||
:label="t('test.run_again')"
|
:label="t('test.run_again')"
|
||||||
class="w-32"
|
|
||||||
@click="runAgain()"
|
@click="runAgain()"
|
||||||
/>
|
/>
|
||||||
<HoppButtonSecondary
|
<HoppButtonSecondary
|
||||||
@@ -115,6 +113,7 @@
|
|||||||
collectionID: tab.document.collectionID,
|
collectionID: tab.document.collectionID,
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
:prev-config="testRunnerConfig"
|
||||||
@hide-modal="showCollectionsRunnerModal = false"
|
@hide-modal="showCollectionsRunnerModal = false"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -127,7 +126,8 @@ import { useVModel } from "@vueuse/core"
|
|||||||
import { useService } from "dioc/vue"
|
import { useService } from "dioc/vue"
|
||||||
import { pipe } from "fp-ts/lib/function"
|
import { pipe } from "fp-ts/lib/function"
|
||||||
import * as TE from "fp-ts/TaskEither"
|
import * as TE from "fp-ts/TaskEither"
|
||||||
import { computed, nextTick, onMounted, ref } from "vue"
|
import { computed, nextTick, onMounted, ref, watch } from "vue"
|
||||||
|
import { useReadonlyStream } from "~/composables/stream"
|
||||||
import { useColorMode } from "~/composables/theming"
|
import { useColorMode } from "~/composables/theming"
|
||||||
import { useToast } from "~/composables/toast"
|
import { useToast } from "~/composables/toast"
|
||||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||||
@@ -141,7 +141,12 @@ import {
|
|||||||
TestRunnerCollectionsAdapter,
|
TestRunnerCollectionsAdapter,
|
||||||
} from "~/helpers/runner/adapter"
|
} from "~/helpers/runner/adapter"
|
||||||
import { getErrorMessage } from "~/helpers/runner/collection-tree"
|
import { getErrorMessage } from "~/helpers/runner/collection-tree"
|
||||||
import { getRESTCollectionByRefId } from "~/newstore/collections"
|
import TeamCollectionAdapter from "~/helpers/teams/TeamCollectionAdapter"
|
||||||
|
import {
|
||||||
|
getRESTCollectionByRefId,
|
||||||
|
getRESTCollectionInheritedProps,
|
||||||
|
restCollectionStore,
|
||||||
|
} from "~/newstore/collections"
|
||||||
import { HoppTab } from "~/services/tab"
|
import { HoppTab } from "~/services/tab"
|
||||||
import { RESTTabService } from "~/services/tab/rest"
|
import { RESTTabService } from "~/services/tab/rest"
|
||||||
import {
|
import {
|
||||||
@@ -154,6 +159,12 @@ const t = useI18n()
|
|||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const colorMode = useColorMode()
|
const colorMode = useColorMode()
|
||||||
|
|
||||||
|
const teamCollectionAdapter = new TeamCollectionAdapter(null)
|
||||||
|
const teamCollectionList = useReadonlyStream(
|
||||||
|
teamCollectionAdapter.collections$,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
const props = defineProps<{ modelValue: HoppTab<HoppTestRunnerDocument> }>()
|
const props = defineProps<{ modelValue: HoppTab<HoppTestRunnerDocument> }>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -218,8 +229,33 @@ const showResult = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const runTests = async () => {
|
const runTests = async () => {
|
||||||
|
const { collectionID, collectionType } = tab.value.document
|
||||||
|
|
||||||
|
const isPersonalWorkspace = collectionType === "my-collections"
|
||||||
|
|
||||||
|
const collections = isPersonalWorkspace
|
||||||
|
? restCollectionStore.value.state
|
||||||
|
: teamCollectionList.value.map(teamCollToHoppRESTColl)
|
||||||
|
|
||||||
|
const collectionInheritedProps = getRESTCollectionInheritedProps(
|
||||||
|
collectionID,
|
||||||
|
collections,
|
||||||
|
collectionType
|
||||||
|
)
|
||||||
|
|
||||||
|
const { auth, headers } = collectionInheritedProps ?? {
|
||||||
|
auth: { authActive: true, authType: "none" },
|
||||||
|
headers: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accommodate collection properties for personal workspace
|
||||||
|
// TODO: Resolve the collection properties computation for team workspaces
|
||||||
|
const resolvedCollection = isPersonalWorkspace
|
||||||
|
? { ...collection.value, auth, headers }
|
||||||
|
: collection.value
|
||||||
|
|
||||||
testRunnerStopRef.value = false // when testRunnerStopRef is false, the test runner will start running
|
testRunnerStopRef.value = false // when testRunnerStopRef is false, the test runner will start running
|
||||||
testRunnerService.runTests(tab, collection.value, {
|
testRunnerService.runTests(tab, resolvedCollection, {
|
||||||
...testRunnerConfig.value,
|
...testRunnerConfig.value,
|
||||||
stopRef: testRunnerStopRef,
|
stopRef: testRunnerStopRef,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
type="number"
|
type="number"
|
||||||
:label="t('collection_runner.delay')"
|
:label="t('collection_runner.delay')"
|
||||||
class="!rounded-r-none !border-r-0"
|
class="!rounded-r-none !border-r-0"
|
||||||
|
:class="{ 'border-red-500': config.delay < 0 }"
|
||||||
input-styles="floating-input !rounded-r-none !border-r-0"
|
input-styles="floating-input !rounded-r-none !border-r-0"
|
||||||
>
|
>
|
||||||
<template #button>
|
<template #button>
|
||||||
@@ -31,6 +32,9 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</HoppSmartInput>
|
</HoppSmartInput>
|
||||||
|
<p v-if="config.delay < 0" class="text-xs text-red-500 mt-1">
|
||||||
|
{{ t("collection_runner.negative_delay") }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -133,6 +137,7 @@
|
|||||||
<HoppButtonPrimary
|
<HoppButtonPrimary
|
||||||
v-if="activeTab === 'test-runner'"
|
v-if="activeTab === 'test-runner'"
|
||||||
:label="`${t('test.run')}`"
|
:label="`${t('test.run')}`"
|
||||||
|
:disabled="config.delay < 0"
|
||||||
:icon="IconPlay"
|
:icon="IconPlay"
|
||||||
outline
|
outline
|
||||||
@click="runTests"
|
@click="runTests"
|
||||||
@@ -157,7 +162,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { refAutoReset } from "@vueuse/core"
|
import { refAutoReset } from "@vueuse/core"
|
||||||
import { computed, ref } from "vue"
|
import { computed, onMounted, ref } from "vue"
|
||||||
import { useI18n } from "~/composables/i18n"
|
import { useI18n } from "~/composables/i18n"
|
||||||
|
|
||||||
import { HoppCollection } from "@hoppscotch/data"
|
import { HoppCollection } from "@hoppscotch/data"
|
||||||
@@ -203,6 +208,7 @@ export type CollectionRunnerData =
|
|||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
sameTab?: boolean
|
sameTab?: boolean
|
||||||
collectionRunnerData: CollectionRunnerData
|
collectionRunnerData: CollectionRunnerData
|
||||||
|
prevConfig?: Partial<TestRunnerConfig>
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -230,6 +236,12 @@ const config = ref<TestRunnerConfig>({
|
|||||||
keepVariableValues: false,
|
keepVariableValues: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.prevConfig) {
|
||||||
|
config.value = { ...config.value, ...props.prevConfig }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const runTests = async () => {
|
const runTests = async () => {
|
||||||
const collectionTree = await getCollectionTree(
|
const collectionTree = await getCollectionTree(
|
||||||
props.collectionRunnerData.type,
|
props.collectionRunnerData.type,
|
||||||
|
|||||||
@@ -27,7 +27,16 @@
|
|||||||
</HoppSmartTabs>
|
</HoppSmartTabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col justify-center test-runner pr-2">
|
<div
|
||||||
|
class="flex flex-col justify-center test-runner pr-2"
|
||||||
|
:class="{
|
||||||
|
hidden:
|
||||||
|
(selectedTestTab === 'passed' &&
|
||||||
|
tab.document.testRunnerMeta.passedTests === 0) ||
|
||||||
|
(selectedTestTab === 'failed' &&
|
||||||
|
tab.document.testRunnerMeta.failedTests === 0),
|
||||||
|
}"
|
||||||
|
>
|
||||||
<HoppSmartTree :expand-all="true" :adapter="collectionAdapter">
|
<HoppSmartTree :expand-all="true" :adapter="collectionAdapter">
|
||||||
<template #content="{ node }">
|
<template #content="{ node }">
|
||||||
<HttpTestResultFolder
|
<HttpTestResultFolder
|
||||||
@@ -60,17 +69,34 @@
|
|||||||
</template>
|
</template>
|
||||||
</HoppSmartTree>
|
</HoppSmartTree>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<HoppSmartPlaceholder
|
||||||
|
v-if="
|
||||||
|
(selectedTestTab === 'passed' &&
|
||||||
|
tab.document.testRunnerMeta.passedTests === 0) ||
|
||||||
|
(selectedTestTab === 'failed' &&
|
||||||
|
tab.document.testRunnerMeta.failedTests === 0)
|
||||||
|
"
|
||||||
|
:src="`/images/states/${colorMode.value}/pack.svg`"
|
||||||
|
:text="
|
||||||
|
selectedTestTab === 'passed'
|
||||||
|
? `${t('collection_runner.no_passed_tests')}`
|
||||||
|
: `${t('collection_runner.no_failed_tests')}`
|
||||||
|
"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { SmartTreeAdapter } from "@hoppscotch/ui"
|
import { SmartTreeAdapter } from "@hoppscotch/ui"
|
||||||
import { ref } from "vue"
|
import { ref } from "vue"
|
||||||
import { useI18n } from "~/composables/i18n"
|
import { useI18n } from "~/composables/i18n"
|
||||||
|
import { useColorMode } from "~/composables/theming"
|
||||||
import { HoppTestRunnerDocument } from "~/helpers/rest/document"
|
import { HoppTestRunnerDocument } from "~/helpers/rest/document"
|
||||||
import { HoppTab } from "~/services/tab"
|
import { HoppTab } from "~/services/tab"
|
||||||
import { TestRunnerRequest } from "~/services/test-runner/test-runner.service"
|
import { TestRunnerRequest } from "~/services/test-runner/test-runner.service"
|
||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
|
const colorMode = useColorMode()
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
tab: HoppTab<HoppTestRunnerDocument>
|
tab: HoppTab<HoppTestRunnerDocument>
|
||||||
|
|||||||
@@ -51,9 +51,12 @@ const getCollectionChildrenIDs = async (collID: string) => {
|
|||||||
return E.left(data.left)
|
return E.left(data.left)
|
||||||
}
|
}
|
||||||
|
|
||||||
collsList.push(...data.right.collection!.children.map((x) => x.id))
|
if (!data.right.collection) return E.right([])
|
||||||
|
|
||||||
if (data.right.collection!.children.length !== BACKEND_PAGE_SIZE) break
|
const children = data.right.collection.children || []
|
||||||
|
collsList.push(...children.map((x) => x.id))
|
||||||
|
|
||||||
|
if (children.length !== BACKEND_PAGE_SIZE) break
|
||||||
}
|
}
|
||||||
|
|
||||||
return E.right(collsList)
|
return E.right(collsList)
|
||||||
@@ -170,10 +173,14 @@ export const getCompleteCollectionTree = (
|
|||||||
collectionID: collID,
|
collectionID: collID,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
TE.map((result) => ({
|
TE.map((result) =>
|
||||||
|
result.collection
|
||||||
|
? {
|
||||||
title: result.collection!.title,
|
title: result.collection!.title,
|
||||||
data: result.collection!.data,
|
data: result.collection!.data,
|
||||||
}))
|
}
|
||||||
|
: null
|
||||||
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
TE.bind("children", () =>
|
TE.bind("children", () =>
|
||||||
@@ -192,8 +199,8 @@ export const getCompleteCollectionTree = (
|
|||||||
id: collID,
|
id: collID,
|
||||||
children,
|
children,
|
||||||
requests,
|
requests,
|
||||||
title: titleAndData.title,
|
title: titleAndData?.title,
|
||||||
data: titleAndData.data,
|
data: titleAndData?.data,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1217,7 +1217,72 @@ export function getRESTCollection(collectionIndex: number) {
|
|||||||
return restCollectionStore.value.state[collectionIndex]
|
return restCollectionStore.value.state[collectionIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRESTCollectionByRefId(ref_id: string) {
|
function computeCollectionInheritedProps(
|
||||||
|
collection: HoppCollection,
|
||||||
|
ref_id: string,
|
||||||
|
type: "my-collections" | "team-collections" = "my-collections",
|
||||||
|
parentAuth: HoppRESTAuth | null = null,
|
||||||
|
parentHeaders: HoppRESTHeaders | null = null
|
||||||
|
): { auth: HoppRESTAuth; headers: HoppRESTHeaders } | null {
|
||||||
|
// Determine the inherited authentication and headers
|
||||||
|
const inheritedAuth =
|
||||||
|
collection.auth?.authType === "inherit" && collection.auth.authActive
|
||||||
|
? (parentAuth ?? { authType: "none", authActive: false })
|
||||||
|
: (collection.auth ?? { authType: "none", authActive: false })
|
||||||
|
|
||||||
|
const inheritedHeaders: HoppRESTHeaders = [
|
||||||
|
...(parentHeaders ?? []),
|
||||||
|
...collection.headers,
|
||||||
|
]
|
||||||
|
|
||||||
|
// Check if the current collection matches the target reference ID
|
||||||
|
const isTargetCollection =
|
||||||
|
type === "my-collections"
|
||||||
|
? collection._ref_id === ref_id
|
||||||
|
: collection.id === ref_id
|
||||||
|
|
||||||
|
if (isTargetCollection) {
|
||||||
|
return {
|
||||||
|
auth: inheritedAuth,
|
||||||
|
headers: inheritedHeaders,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively search in folders
|
||||||
|
for (const folder of collection.folders) {
|
||||||
|
const result = computeCollectionInheritedProps(
|
||||||
|
folder,
|
||||||
|
ref_id,
|
||||||
|
type,
|
||||||
|
inheritedAuth,
|
||||||
|
inheritedHeaders
|
||||||
|
)
|
||||||
|
if (result) return result // Return as soon as a match is found
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRESTCollectionInheritedProps(
|
||||||
|
collectionID: string,
|
||||||
|
collections: HoppCollection[] = restCollectionStore.value.state,
|
||||||
|
type: "my-collections" | "team-collections" = "my-collections"
|
||||||
|
): { auth: HoppRESTAuth; headers: HoppRESTHeaders } | null {
|
||||||
|
for (const collection of collections) {
|
||||||
|
const result = computeCollectionInheritedProps(
|
||||||
|
collection,
|
||||||
|
collectionID,
|
||||||
|
type
|
||||||
|
)
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
function findCollection(
|
function findCollection(
|
||||||
collection: HoppCollection,
|
collection: HoppCollection,
|
||||||
ref_id: string
|
ref_id: string
|
||||||
@@ -1233,6 +1298,8 @@ export function getRESTCollectionByRefId(ref_id: string) {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getRESTCollectionByRefId(ref_id: string) {
|
||||||
for (const collection of restCollectionStore.value.state) {
|
for (const collection of restCollectionStore.value.state) {
|
||||||
const found = findCollection(collection, ref_id)
|
const found = findCollection(collection, ref_id)
|
||||||
if (found) {
|
if (found) {
|
||||||
|
|||||||
@@ -510,25 +510,6 @@ export const REST_TAB_STATE_SCHEMA = z
|
|||||||
z.object({
|
z.object({
|
||||||
tabID: z.string(),
|
tabID: z.string(),
|
||||||
doc: z.union([
|
doc: z.union([
|
||||||
z.object({
|
|
||||||
// !Versioned entity
|
|
||||||
request: entityReference(HoppRESTRequest),
|
|
||||||
type: z.literal("request").catch("request"),
|
|
||||||
isDirty: z.boolean(),
|
|
||||||
saveContext: z.optional(HoppRESTSaveContextSchema),
|
|
||||||
response: z.optional(z.nullable(HoppRESTResponseSchema)),
|
|
||||||
testResults: z.optional(z.nullable(HoppTestResultSchema)),
|
|
||||||
responseTabPreference: z.optional(z.string()),
|
|
||||||
optionTabPreference: z.optional(z.enum(validRestOperations)),
|
|
||||||
inheritedProperties: z.optional(HoppInheritedPropertySchema),
|
|
||||||
cancelFunction: z.optional(z.function()),
|
|
||||||
}),
|
|
||||||
z.object({
|
|
||||||
type: z.literal("example-response").catch("example-response"),
|
|
||||||
response: HoppRESTRequestResponse,
|
|
||||||
saveContext: z.optional(HoppRESTSaveContextSchema),
|
|
||||||
isDirty: z.boolean(),
|
|
||||||
}),
|
|
||||||
z.object({
|
z.object({
|
||||||
type: z.literal("test-runner").catch("test-runner"),
|
type: z.literal("test-runner").catch("test-runner"),
|
||||||
config: z.object({
|
config: z.object({
|
||||||
@@ -556,6 +537,25 @@ export const REST_TAB_STATE_SCHEMA = z
|
|||||||
testResults: z.optional(z.nullable(HoppTestResultSchema)),
|
testResults: z.optional(z.nullable(HoppTestResultSchema)),
|
||||||
isDirty: z.boolean(),
|
isDirty: z.boolean(),
|
||||||
}),
|
}),
|
||||||
|
z.object({
|
||||||
|
// !Versioned entity
|
||||||
|
request: entityReference(HoppRESTRequest),
|
||||||
|
type: z.literal("request").catch("request"),
|
||||||
|
isDirty: z.boolean(),
|
||||||
|
saveContext: z.optional(HoppRESTSaveContextSchema),
|
||||||
|
response: z.optional(z.nullable(HoppRESTResponseSchema)),
|
||||||
|
testResults: z.optional(z.nullable(HoppTestResultSchema)),
|
||||||
|
responseTabPreference: z.optional(z.string()),
|
||||||
|
optionTabPreference: z.optional(z.enum(validRestOperations)),
|
||||||
|
inheritedProperties: z.optional(HoppInheritedPropertySchema),
|
||||||
|
cancelFunction: z.optional(z.function()),
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal("example-response").catch("example-response"),
|
||||||
|
response: HoppRESTRequestResponse,
|
||||||
|
saveContext: z.optional(HoppRESTSaveContextSchema),
|
||||||
|
isDirty: z.boolean(),
|
||||||
|
}),
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -39,6 +39,17 @@ export class RESTTabService extends TabService<HoppTabDocument> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tab.document.type === "test-runner") {
|
||||||
|
return {
|
||||||
|
tabID: tab.id,
|
||||||
|
doc: {
|
||||||
|
...tab.document,
|
||||||
|
request: null,
|
||||||
|
response: null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tabID: tab.id,
|
tabID: tab.id,
|
||||||
doc: {
|
doc: {
|
||||||
|
|||||||
Reference in New Issue
Block a user