Skip to content

Commit

Permalink
feat: test runner result and response
Browse files Browse the repository at this point in the history
  • Loading branch information
anwarulislam committed Dec 14, 2023
1 parent 03d5dc8 commit 2bbdf25
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 107 deletions.
4 changes: 2 additions & 2 deletions packages/hoppscotch-common/src/components/embeds/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ import { useStreamSubscriber } from "~/composables/stream"
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
import { runRESTRequest$ } from "~/helpers/RequestRunner"
import { HoppTab } from "~/services/tab"
import { HoppRESTDocument } from "~/helpers/rest/document"
import { HoppRequestDocument } from "~/helpers/rest/document"
import IconSave from "~icons/lucide/save"
const t = useI18n()
const toast = useToast()
const props = defineProps<{
modelTab: HoppTab<HoppRESTDocument>
modelTab: HoppTab<HoppRequestDocument>
properties: string[]
sharedRequestID: string
}>()
Expand Down
8 changes: 5 additions & 3 deletions packages/hoppscotch-common/src/components/http/Request.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@
<HoppButtonPrimary
id="send"
v-tippy="{ theme: 'tooltip', delay: [500, 20], allowHTML: true }"
:title="`${t('action.send')} <kbd>${getSpecialKey()}</kbd><kbd>↩</kbd>`"
:title="`${t(
'action.send'
)} <kbd>${getSpecialKey()}</kbd><kbd>↩</kbd>`"
:label="`${!loading ? t('action.send') : t('action.cancel')}`"
class="min-w-[5rem] flex-1 rounded-r-none"
@click="!loading ? newSendRequest() : cancelRequest()"
Expand Down Expand Up @@ -258,7 +260,7 @@ import { useService } from "dioc/vue"
import { InspectionService } from "~/services/inspection"
import { InterceptorService } from "~/services/interceptor.service"
import { HoppTab } from "~/services/tab"
import { HoppTabDocument } from "~/helpers/rest/document"
import { HoppRequestDocument } from "~/helpers/rest/document"
import { RESTTabService } from "~/services/tab/rest"
import { getMethodLabelColor } from "~/helpers/rest/labelColoring"
Expand All @@ -282,7 +284,7 @@ const toast = useToast()
const { subscribeToStream } = useStreamSubscriber()
const props = defineProps<{ modelValue: HoppTab<HoppTabDocument> }>()
const props = defineProps<{ modelValue: HoppTab<HoppRequestDocument> }>()
const emit = defineEmits(["update:modelValue"])
const tab = useVModel(props, "modelValue", emit)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<div class="flex items-stretch group">
<div class="flex items-stretch group ml-4">
<button
@click="selectRequest()"
class="w-full rounded ml-4 px-6 py-3 transition cursor-pointer focus:outline-none hover:active hover:bg-primaryLight hover:text-secondaryDark"
class="w-full rounded px-6 py-3 transition cursor-pointer focus:outline-none hover:active hover:bg-primaryLight hover:text-secondaryDark"
>
<div class="flex gap-4 mb-1">
<span
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
import { useI18n } from "@composables/i18n"
import { useVModel } from "@vueuse/core"
import { computed, ref } from "vue"
import { HoppTabDocument } from "~/helpers/rest/document"
import { HoppTestRunnerDocument } from "~/helpers/rest/document"
import { HoppTab } from "~/services/tab"
import IconPlus from "~icons/lucide/plus"
Expand All @@ -89,10 +89,10 @@ const testRunnerConfig = ref<TestRunnerConfig>({
keepVariableValues: false,
})
const props = defineProps<{ modelValue: HoppTab<HoppTabDocument> }>()
const props = defineProps<{ modelValue: HoppTab<HoppTestRunnerDocument> }>()
const emit = defineEmits<{
(e: "update:modelValue", val: HoppTab<HoppTabDocument>): void
(e: "update:modelValue", val: HoppTab<HoppTestRunnerDocument>): void
}>()
const collectionName = computed(() => {
Expand Down
150 changes: 68 additions & 82 deletions packages/hoppscotch-common/src/helpers/RequestRunner.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Environment } from "@hoppscotch/data"
import { SandboxTestResult, TestDescriptor } from "@hoppscotch/js-sandbox"
import {
SandboxTestResult,
TestDescriptor,
TestResult,
} from "@hoppscotch/js-sandbox"
import { runTestScript } from "@hoppscotch/js-sandbox/web"
import * as A from "fp-ts/Array"
import * as E from "fp-ts/Either"
Expand Down Expand Up @@ -29,8 +33,8 @@ import { HoppRESTResponse } from "./types/HoppRESTResponse"
import { HoppTestData, HoppTestResult } from "./types/HoppTestResult"
import { getEffectiveRESTRequest } from "./utils/EffectiveURL"
import { isJSONContentType } from "./utils/contenttypes"
import { HoppTabDocument } from "./rest/document"
import { TestRunnerRequest } from "~/services/test-runner/test-runner.service"
import { HoppRequestDocument } from "./rest/document"
import { HoppRESTRequest } from "@hoppscotch/data"

export const getTestableBody = (
res: HoppRESTResponse & { type: "success" | "fail" }
Expand Down Expand Up @@ -69,7 +73,7 @@ export const executedResponses$ = new Subject<
>()

export function runRESTRequest$(
tab: Ref<HoppTab<HoppTabDocument>>
tab: Ref<HoppTab<HoppRequestDocument>>
): [
() => void,
Promise<
Expand Down Expand Up @@ -133,35 +137,7 @@ export function runRESTRequest$(

setGlobalEnvVariables(runResult.right.envs.global)

if (
environmentsStore.value.selectedEnvironmentIndex.type === "MY_ENV"
) {
const env = getEnvironment({
type: "MY_ENV",
index: environmentsStore.value.selectedEnvironmentIndex.index,
})
updateEnvironment(
environmentsStore.value.selectedEnvironmentIndex.index,
{
...env,
variables: runResult.right.envs.selected,
}
)
} else if (
environmentsStore.value.selectedEnvironmentIndex.type ===
"TEAM_ENV"
) {
const env = getEnvironment({
type: "TEAM_ENV",
})
pipe(
updateTeamEnvironment(
JSON.stringify(runResult.right.envs.selected),
environmentsStore.value.selectedEnvironmentIndex.teamEnvID,
env.name
)
)()
}
updateEnvsFromTestScript(runResult.right)
} else {
tab.value.document.testResults = {
description: "",
Expand Down Expand Up @@ -193,12 +169,43 @@ export function runRESTRequest$(
return [cancel, res]
}

export function runTestRunnerRequest(
request: TestRunnerRequest
): Promise<
E.Left<"script_fail" | "cancellation"> | E.Right<Observable<HoppRESTResponse>>
function updateEnvsFromTestScript(runResult: TestResult) {
setGlobalEnvVariables(runResult.envs.global)

if (environmentsStore.value.selectedEnvironmentIndex.type === "MY_ENV") {
const env = getEnvironment({
type: "MY_ENV",
index: environmentsStore.value.selectedEnvironmentIndex.index,
})
updateEnvironment(environmentsStore.value.selectedEnvironmentIndex.index, {
...env,
variables: runResult.envs.selected,
})
} else if (
environmentsStore.value.selectedEnvironmentIndex.type === "TEAM_ENV"
) {
const env = getEnvironment({
type: "TEAM_ENV",
})
pipe(
updateTeamEnvironment(
JSON.stringify(runResult.envs.selected),
environmentsStore.value.selectedEnvironmentIndex.teamEnvID,
env.name
)
)()
}
}

export function runTestRunnerRequest(request: HoppRESTRequest): Promise<
| E.Left<"script_fail">
| E.Right<{
response: HoppRESTResponse
testResult: HoppTestResult
}>
| undefined
> {
const res = getFinalEnvsFromPreRequest(
return getFinalEnvsFromPreRequest(
request.preRequestScript,
getCombinedEnvVariables()
).then((envs) => {
Expand All @@ -214,15 +221,11 @@ export function runTestRunnerRequest(

const [stream] = createRESTNetworkRequestStream(effectiveRequest)

const subscription = stream
const requestResult = stream
.pipe(filter((res) => res.type === "success" || res.type === "fail"))
.subscribe(async (res) => {
if (res.type === "success" || res.type === "fail") {
executedResponses$.next(
// @ts-expect-error Typescript can't figure out this inference for some reason
res
)

.toPromise()
.then(async (res) => {
if (res?.type === "success" || res?.type === "fail") {
const runResult = await runTestScript(
res.req.testScript,
envs.right,
Expand All @@ -234,41 +237,20 @@ export function runTestRunnerRequest(
)

if (E.isRight(runResult)) {
request.testResults = translateToSandboxTestResults(runResult.right)
const sandboxTestResult = translateToSandboxTestResults(
runResult.right
)

setGlobalEnvVariables(runResult.right.envs.global)

if (
environmentsStore.value.selectedEnvironmentIndex.type === "MY_ENV"
) {
const env = getEnvironment({
type: "MY_ENV",
index: environmentsStore.value.selectedEnvironmentIndex.index,
})
updateEnvironment(
environmentsStore.value.selectedEnvironmentIndex.index,
{
...env,
variables: runResult.right.envs.selected,
}
)
} else if (
environmentsStore.value.selectedEnvironmentIndex.type ===
"TEAM_ENV"
) {
const env = getEnvironment({
type: "TEAM_ENV",
})
pipe(
updateTeamEnvironment(
JSON.stringify(runResult.right.envs.selected),
environmentsStore.value.selectedEnvironmentIndex.teamEnvID,
env.name
)
)()
}
updateEnvsFromTestScript(runResult.right)

return E.right({
response: res,
testResult: sandboxTestResult,
})
} else {
request.testResults = {
const sandboxTestResult = {
description: "",
expectResults: [],
tests: [],
Expand All @@ -286,16 +268,20 @@ export function runTestRunnerRequest(
},
scriptError: true,
}
return E.right({
response: res,
testResult: sandboxTestResult,
})
}

subscription.unsubscribe()
}
})

return E.right(stream)
})
if (requestResult) {
return requestResult
}

return res
return E.left("script_fail")
})
}

const getAddedEnvVariables = (
Expand Down
2 changes: 1 addition & 1 deletion packages/hoppscotch-common/src/helpers/rest/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export type HoppTestRunnerDocument = {
/**
* The request as it is in the document
*/
result: HoppCollection<HoppRESTRequest>
result?: HoppCollection<HoppRESTRequest>

/**
* Info about where this request should be saved.
Expand Down
4 changes: 2 additions & 2 deletions packages/hoppscotch-common/src/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<!-- When document.type === 'request' the tab type is HoppTab<HoppRequestDocument>-->
<HttpRequestTab
v-if="tab.document.type === 'request'"
:model-value="(tab as HoppTab<HoppRequestDocument>)"
:model-value="tab"
@update:model-value="onTabUpdate"
/>
<!-- END Render TabContents -->
Expand Down Expand Up @@ -155,7 +155,7 @@ import { ResponseInspectorService } from "~/services/inspection/inspectors/respo
import { cloneDeep } from "lodash-es"
import { RESTTabService } from "~/services/tab/rest"
import { HoppTab, PersistableTabState } from "~/services/tab"
import { HoppRequestDocument, HoppTabDocument } from "~/helpers/rest/document"
import { HoppTabDocument } from "~/helpers/rest/document"
const savingRequest = ref(false)
const confirmingCloseForTabID = ref<string | null>(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TestRunnerConfig } from "~/components/http/test/Runner.vue"
import { runTestRunnerRequest } from "~/helpers/RequestRunner"
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
import { HoppTestResult } from "~/helpers/types/HoppTestResult"
import * as E from "fp-ts/Either"

export type TestRunState = {
status: "idle" | "running" | "stopped"
Expand Down Expand Up @@ -41,28 +42,35 @@ export class TestRunnerService extends Service {
super()
}

private runTestRequest(
private async runTestRequest(
state: Ref<TestRunState>,
request: HoppRESTRequest,
request: TestRunnerRequest,
options: TestRunnerOptions
) {
runTestRunnerRequest(request)
const results = await runTestRunnerRequest(request)
if (results && E.isRight(results)) {
const { response, testResult } = results.right
// Use response and testResult
request.testResults = testResult
request.response = response

console.log(request)
} else {
console.error("Script failed")
}
}

private runTestCollection(
private async runTestCollection(
state: Ref<TestRunState>,
collection: HoppCollection<TestRunnerRequest>,
options: TestRunnerOptions
) {
if (collection.requests.length) {
for (const request of collection.requests) {
this.runTestRequest(state, request, options)
}
for (const folder of collection.folders) {
await this.runTestCollection(state, folder, options)
}
if (collection.folders.length) {
for (const folder of collection.folders) {
this.runTestCollection(state, folder, options)
}

for (const request of collection.requests) {
await this.runTestRequest(state, request, options)
}
}

Expand Down

0 comments on commit 2bbdf25

Please sign in to comment.