Merge branch 'master' into dependabot/npm_and_yarn/nuxtjs/toast-3.3.1
This commit is contained in:
@@ -286,6 +286,11 @@ hr {
|
|||||||
.info:not(.toasted) {
|
.info:not(.toasted) {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
color: var(--fg-light-color);
|
color: var(--fg-light-color);
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-color {
|
.bg-color {
|
||||||
@@ -535,11 +540,6 @@ ol {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
|
||||||
&.response-headers {
|
|
||||||
display: inline-flex;
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul,
|
ul,
|
||||||
ol {
|
ol {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ TODO:
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="collections.length === 0" class="info">
|
<p v-if="collections.length === 0" class="info">
|
||||||
Create new collection
|
<i class="material-icons">help_outline</i> Create new collection
|
||||||
</p>
|
</p>
|
||||||
<div class="virtual-list">
|
<div class="virtual-list">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -76,9 +76,6 @@ TODO:
|
|||||||
@edit-request="editRequest($event)"
|
@edit-request="editRequest($event)"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="collections.length === 0">
|
|
||||||
<label>Collections are empty</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<nuxt-link :to="localePath('doc')" :aria-label="$t('documentation')">
|
<nuxt-link :to="localePath('doc')" :aria-label="$t('documentation')">
|
||||||
|
|||||||
@@ -35,14 +35,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
|
||||||
id="variableList"
|
|
||||||
readonly
|
|
||||||
v-textarea-auto-height="variableString"
|
|
||||||
v-model="variableString"
|
|
||||||
:placeholder="$t('add_one_variable')"
|
|
||||||
rows="1"
|
|
||||||
></textarea>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-for="(variable, index) in this.editingEnvCopy.variables" :key="index">
|
<ul v-for="(variable, index) in this.editingEnvCopy.variables" :key="index">
|
||||||
@@ -114,13 +106,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import textareaAutoHeight from "~/directives/textareaAutoHeight"
|
|
||||||
import { fb } from "~/helpers/fb"
|
import { fb } from "~/helpers/fb"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
directives: {
|
|
||||||
textareaAutoHeight,
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
editingEnvironment: Object,
|
editingEnvironment: Object,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="environments.length === 0" class="info">
|
<p v-if="environments.length === 0" class="info">
|
||||||
Create new environment
|
<i class="material-icons">help_outline</i> Create new environment
|
||||||
</p>
|
</p>
|
||||||
<div class="virtual-list">
|
<div class="virtual-list">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -37,9 +37,6 @@
|
|||||||
@select-environment="$emit('use-environment', environment)"
|
@select-environment="$emit('use-environment', environment)"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="environments.length === 0">
|
|
||||||
<label>Environments are empty</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</pw-section>
|
</pw-section>
|
||||||
|
|||||||
@@ -154,7 +154,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p v-if="history.length === 0" class="info">
|
<p v-if="history.length === 0" class="info">
|
||||||
{{ $t("history_empty") }}
|
<i class="material-icons">schedule</i> {{ $t("history_empty") }}
|
||||||
</p>
|
</p>
|
||||||
<div v-if="history.length !== 0">
|
<div v-if="history.length !== 0">
|
||||||
<div class="flex-wrap" v-if="!isClearingHistory">
|
<div class="flex-wrap" v-if="!isClearingHistory">
|
||||||
@@ -221,7 +221,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex-wrap" v-else>
|
<div class="flex-wrap" v-else>
|
||||||
<label for="clear-history-button" class="info">
|
<label for="clear-history-button" class="info">
|
||||||
{{ $t("are_you_sure") }}
|
<i class="material-icons">help_outline</i> {{ $t("are_you_sure") }}
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
|||||||
44
components/lenses/ResponseBodyRenderer.vue
Normal file
44
components/lenses/ResponseBodyRenderer.vue
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<tabs>
|
||||||
|
<tab
|
||||||
|
v-for="(lens, index) in validLenses"
|
||||||
|
:key="lens.lensName"
|
||||||
|
:id="lens.lensName"
|
||||||
|
:label="lens.lensName"
|
||||||
|
:selected="index === 0"
|
||||||
|
>
|
||||||
|
<component :is="lens.renderer" :response="response" />
|
||||||
|
</tab>
|
||||||
|
<tab
|
||||||
|
v-if="Object.keys(response.headers).length !== 0"
|
||||||
|
id="headers"
|
||||||
|
:label="`Headers \xA0 • \xA0 ${Object.keys(response.headers).length}`"
|
||||||
|
>
|
||||||
|
<headers :headers="response.headers" />
|
||||||
|
</tab>
|
||||||
|
</tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getSuitableLenses, getLensRenderers } from "~/helpers/lenses/lenses"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
tabs: () => import("../ui/tabs"),
|
||||||
|
tab: () => import("../ui/tab"),
|
||||||
|
headers: () => import("./headers"),
|
||||||
|
// Lens Renderers
|
||||||
|
...getLensRenderers(),
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
validLenses() {
|
||||||
|
return getSuitableLenses(this.response)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
17
components/lenses/headers.vue
Normal file
17
components/lenses/headers.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ul v-for="(value, key) in headers" :key="key">
|
||||||
|
<li>
|
||||||
|
<input :value="`${key} → ${value}`" :name="key" class="bg-color" readonly />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
headers: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
153
components/lenses/renderers/HTMLLensRenderer.vue
Normal file
153
components/lenses/renderers/HTMLLensRenderer.vue
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<label for="body">{{ $t("response") }}</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="ToggleExpandResponse"
|
||||||
|
ref="ToggleExpandResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="{
|
||||||
|
content: !expandResponse ? $t('expand_response') : $t('collapse_response'),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i class="material-icons">
|
||||||
|
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
||||||
|
</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="response.body"
|
||||||
|
class="icon"
|
||||||
|
@click.prevent="togglePreview"
|
||||||
|
v-tooltip="{
|
||||||
|
content: previewEnabled ? $t('hide_preview') : $t('preview_html'),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i class="material-icons">
|
||||||
|
{{ !previewEnabled ? "visibility" : "visibility_off" }}
|
||||||
|
</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="downloadResponse"
|
||||||
|
ref="downloadResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="$t('download_file')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">save_alt</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="copyResponse"
|
||||||
|
ref="copyResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="$t('copy_response')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">content_copy</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="response-details-wrapper">
|
||||||
|
<Editor
|
||||||
|
:value="responseBodyText"
|
||||||
|
:lang="'html'"
|
||||||
|
:options="{
|
||||||
|
maxLines: responseBodyMaxLines,
|
||||||
|
minLines: '16',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
readOnly: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<iframe
|
||||||
|
:class="{ hidden: !previewEnabled }"
|
||||||
|
class="covers-response"
|
||||||
|
ref="previewFrame"
|
||||||
|
src="about:blank"
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import AceEditor from "../../ui/ace-editor"
|
||||||
|
import TextContentRendererMixin from "./mixins/TextContentRendererMixin"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Editor: AceEditor,
|
||||||
|
},
|
||||||
|
mixins: [TextContentRendererMixin],
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expandResponse: false,
|
||||||
|
responseBodyMaxLines: 16,
|
||||||
|
doneButton: '<i class="material-icons">done</i>',
|
||||||
|
downloadButton: '<i class="material-icons">save_alt</i>',
|
||||||
|
copyButton: '<i class="material-icons">content_copy</i>',
|
||||||
|
previewEnabled: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ToggleExpandResponse() {
|
||||||
|
this.expandResponse = !this.expandResponse
|
||||||
|
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
||||||
|
},
|
||||||
|
downloadResponse() {
|
||||||
|
const dataToWrite = this.responseBodyText
|
||||||
|
const file = new Blob([dataToWrite], { type: "text/html" })
|
||||||
|
const a = document.createElement("a")
|
||||||
|
const url = URL.createObjectURL(file)
|
||||||
|
a.href = url
|
||||||
|
// TODO get uri from meta
|
||||||
|
a.download = `response on ${Date()}`.replace(/\./g, "[dot]")
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("download_started"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(a)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.downloadButton
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
copyResponse() {
|
||||||
|
this.$refs.copyResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("copied_to_clipboard"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
const aux = document.createElement("textarea")
|
||||||
|
const copy = this.responseBodyText
|
||||||
|
aux.innerText = copy
|
||||||
|
document.body.appendChild(aux)
|
||||||
|
aux.select()
|
||||||
|
document.execCommand("copy")
|
||||||
|
document.body.removeChild(aux)
|
||||||
|
setTimeout(() => (this.$refs.copyResponse.innerHTML = this.copyButton), 1000)
|
||||||
|
},
|
||||||
|
togglePreview() {
|
||||||
|
this.previewEnabled = !this.previewEnabled
|
||||||
|
if (this.previewEnabled) {
|
||||||
|
if (this.$refs.previewFrame.getAttribute("data-previewing-url") === this.url) return
|
||||||
|
// Use DOMParser to parse document HTML.
|
||||||
|
const previewDocument = new DOMParser().parseFromString(this.responseBodyText, "text/html")
|
||||||
|
// Inject <base href="..."> tag to head, to fix relative CSS/HTML paths.
|
||||||
|
previewDocument.head.innerHTML =
|
||||||
|
`<base href="${this.url}">` + previewDocument.head.innerHTML
|
||||||
|
// Finally, set the iframe source to the resulting HTML.
|
||||||
|
this.$refs.previewFrame.srcdoc = previewDocument.documentElement.outerHTML
|
||||||
|
this.$refs.previewFrame.setAttribute("data-previewing-url", this.url)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
102
components/lenses/renderers/ImageLensRenderer.vue
Normal file
102
components/lenses/renderers/ImageLensRenderer.vue
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<label for="body">{{ $t("response") }}</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="downloadResponse"
|
||||||
|
ref="downloadResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="$t('download_file')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">save_alt</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="response-details-wrapper">
|
||||||
|
<img class="response-image" :src="imageSource" />
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.response-image {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
imageSource: "",
|
||||||
|
doneButton: '<i class="material-icons">done</i>',
|
||||||
|
downloadButton: '<i class="material-icons">save_alt</i>',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
responseType() {
|
||||||
|
return (this.response.headers["content-type"] || "").split(";")[0].toLowerCase()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
response: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
this.imageSource = ""
|
||||||
|
|
||||||
|
const buf = this.response.body
|
||||||
|
const bytes = new Uint8Array(buf)
|
||||||
|
const blob = new Blob([bytes.buffer])
|
||||||
|
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
this.imageSource = e.target.result
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(blob)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.imageSource = ""
|
||||||
|
|
||||||
|
const buf = this.response.body
|
||||||
|
const bytes = new Uint8Array(buf)
|
||||||
|
const blob = new Blob([bytes.buffer])
|
||||||
|
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
this.imageSource = e.target.result
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(blob)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
downloadResponse() {
|
||||||
|
const dataToWrite = this.response.body
|
||||||
|
const file = new Blob([dataToWrite], { type: this.responseType })
|
||||||
|
const a = document.createElement("a")
|
||||||
|
const url = URL.createObjectURL(file)
|
||||||
|
a.href = url
|
||||||
|
// TODO get uri from meta
|
||||||
|
a.download = `response on ${Date()}`.replace(/\./g, "[dot]")
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("download_started"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(a)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.downloadButton
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
149
components/lenses/renderers/JSONLensRenderer.vue
Normal file
149
components/lenses/renderers/JSONLensRenderer.vue
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<label for="body">{{ $t("response") }}</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="ToggleExpandResponse"
|
||||||
|
ref="ToggleExpandResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="{
|
||||||
|
content: !expandResponse ? $t('expand_response') : $t('collapse_response'),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i class="material-icons">
|
||||||
|
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
||||||
|
</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="downloadResponse"
|
||||||
|
ref="downloadResponse"
|
||||||
|
v-if="response.body && canDownloadResponse"
|
||||||
|
v-tooltip="$t('download_file')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">save_alt</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="copyResponse"
|
||||||
|
ref="copyResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="$t('copy_response')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">content_copy</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="valid-warning" v-if="jsonInvalid">
|
||||||
|
<p class="info"><i class="material-icons">error_outline</i> Invalid JSON</p>
|
||||||
|
</div>
|
||||||
|
<div id="response-details-wrapper">
|
||||||
|
<Editor
|
||||||
|
:value="jsonBodyText"
|
||||||
|
:lang="'json'"
|
||||||
|
:options="{
|
||||||
|
maxLines: responseBodyMaxLines,
|
||||||
|
minLines: '16',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
readOnly: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AceEditor from "../../ui/ace-editor"
|
||||||
|
import { isJSONContentType } from "~/helpers/utils/contenttypes"
|
||||||
|
import TextContentRendererMixin from "./mixins/TextContentRendererMixin"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Editor: AceEditor,
|
||||||
|
},
|
||||||
|
mixins: [TextContentRendererMixin],
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expandResponse: false,
|
||||||
|
jsonInvalid: false,
|
||||||
|
responseBodyMaxLines: 16,
|
||||||
|
doneButton: '<i class="material-icons">done</i>',
|
||||||
|
downloadButton: '<i class="material-icons">save_alt</i>',
|
||||||
|
copyButton: '<i class="material-icons">content_copy</i>',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
jsonBodyText() {
|
||||||
|
try {
|
||||||
|
this.jsonInvalid = false
|
||||||
|
return JSON.stringify(JSON.parse(this.responseBodyText), null, 2)
|
||||||
|
} catch (e) {
|
||||||
|
// Most probs invalid JSON was returned, so drop prettification (should we warn ?)
|
||||||
|
this.jsonInvalid = true
|
||||||
|
return this.responseBodyText
|
||||||
|
}
|
||||||
|
},
|
||||||
|
responseType() {
|
||||||
|
return (this.response.headers["content-type"] || "").split(";")[0].toLowerCase()
|
||||||
|
},
|
||||||
|
canDownloadResponse() {
|
||||||
|
return (
|
||||||
|
this.response &&
|
||||||
|
this.response.headers &&
|
||||||
|
this.response.headers["content-type"] &&
|
||||||
|
isJSONContentType(this.response.headers["content-type"])
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ToggleExpandResponse() {
|
||||||
|
this.expandResponse = !this.expandResponse
|
||||||
|
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
||||||
|
},
|
||||||
|
downloadResponse() {
|
||||||
|
const dataToWrite = this.responseBodyText
|
||||||
|
const file = new Blob([dataToWrite], { type: this.responseType })
|
||||||
|
const a = document.createElement("a")
|
||||||
|
const url = URL.createObjectURL(file)
|
||||||
|
a.href = url
|
||||||
|
// TODO get uri from meta
|
||||||
|
a.download = `response on ${Date()}`.replace(/\./g, "[dot]")
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("download_started"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(a)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.downloadButton
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
copyResponse() {
|
||||||
|
this.$refs.copyResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("copied_to_clipboard"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
const aux = document.createElement("textarea")
|
||||||
|
const copy = this.responseBodyText
|
||||||
|
aux.innerText = copy
|
||||||
|
document.body.appendChild(aux)
|
||||||
|
aux.select()
|
||||||
|
document.execCommand("copy")
|
||||||
|
document.body.removeChild(aux)
|
||||||
|
setTimeout(() => (this.$refs.copyResponse.innerHTML = this.copyButton), 1000)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
134
components/lenses/renderers/RawLensRenderer.vue
Normal file
134
components/lenses/renderers/RawLensRenderer.vue
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<label for="body">{{ $t("response") }}</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="ToggleExpandResponse"
|
||||||
|
ref="ToggleExpandResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="{
|
||||||
|
content: !expandResponse ? $t('expand_response') : $t('collapse_response'),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i class="material-icons">
|
||||||
|
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
||||||
|
</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="downloadResponse"
|
||||||
|
ref="downloadResponse"
|
||||||
|
v-if="response.body && canDownloadResponse"
|
||||||
|
v-tooltip="$t('download_file')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">save_alt</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="copyResponse"
|
||||||
|
ref="copyResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="$t('copy_response')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">content_copy</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="response-details-wrapper">
|
||||||
|
<Editor
|
||||||
|
:value="responseBodyText"
|
||||||
|
:lang="'plain_text'"
|
||||||
|
:options="{
|
||||||
|
maxLines: responseBodyMaxLines,
|
||||||
|
minLines: '16',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
readOnly: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import AceEditor from "../../ui/ace-editor"
|
||||||
|
import { isJSONContentType } from "~/helpers/utils/contenttypes"
|
||||||
|
import TextContentRendererMixin from "./mixins/TextContentRendererMixin"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Editor: AceEditor,
|
||||||
|
},
|
||||||
|
mixins: [TextContentRendererMixin],
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expandResponse: false,
|
||||||
|
responseBodyMaxLines: 16,
|
||||||
|
doneButton: '<i class="material-icons">done</i>',
|
||||||
|
downloadButton: '<i class="material-icons">save_alt</i>',
|
||||||
|
copyButton: '<i class="material-icons">content_copy</i>',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
responseType() {
|
||||||
|
return (this.response.headers["content-type"] || "").split(";")[0].toLowerCase()
|
||||||
|
},
|
||||||
|
canDownloadResponse() {
|
||||||
|
return (
|
||||||
|
this.response &&
|
||||||
|
this.response.headers &&
|
||||||
|
this.response.headers["content-type"] &&
|
||||||
|
isJSONContentType(this.response.headers["content-type"])
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ToggleExpandResponse() {
|
||||||
|
this.expandResponse = !this.expandResponse
|
||||||
|
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
||||||
|
},
|
||||||
|
downloadResponse() {
|
||||||
|
const dataToWrite = this.responseBodyText
|
||||||
|
const file = new Blob([dataToWrite], { type: this.responseType })
|
||||||
|
const a = document.createElement("a")
|
||||||
|
const url = URL.createObjectURL(file)
|
||||||
|
a.href = url
|
||||||
|
// TODO get uri from meta
|
||||||
|
a.download = `response on ${Date()}`.replace(/\./g, "[dot]")
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("download_started"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(a)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.downloadButton
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
copyResponse() {
|
||||||
|
this.$refs.copyResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("copied_to_clipboard"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
const aux = document.createElement("textarea")
|
||||||
|
const copy = this.responseBodyText
|
||||||
|
aux.innerText = copy
|
||||||
|
document.body.appendChild(aux)
|
||||||
|
aux.select()
|
||||||
|
document.execCommand("copy")
|
||||||
|
document.body.removeChild(aux)
|
||||||
|
setTimeout(() => (this.$refs.copyResponse.innerHTML = this.copyButton), 1000)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
125
components/lenses/renderers/XMLLensRenderer.vue
Normal file
125
components/lenses/renderers/XMLLensRenderer.vue
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<label for="body">{{ $t("response") }}</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="ToggleExpandResponse"
|
||||||
|
ref="ToggleExpandResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="{
|
||||||
|
content: !expandResponse ? $t('expand_response') : $t('collapse_response'),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i class="material-icons">
|
||||||
|
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
||||||
|
</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="downloadResponse"
|
||||||
|
ref="downloadResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="$t('download_file')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">save_alt</i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="copyResponse"
|
||||||
|
ref="copyResponse"
|
||||||
|
v-if="response.body"
|
||||||
|
v-tooltip="$t('copy_response')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">content_copy</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="response-details-wrapper">
|
||||||
|
<Editor
|
||||||
|
:value="responseBodyText"
|
||||||
|
:lang="'xml'"
|
||||||
|
:options="{
|
||||||
|
maxLines: responseBodyMaxLines,
|
||||||
|
minLines: '16',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
readOnly: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import AceEditor from "../../ui/ace-editor"
|
||||||
|
import TextContentRendererMixin from "./mixins/TextContentRendererMixin"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Editor: AceEditor,
|
||||||
|
},
|
||||||
|
mixins: [TextContentRendererMixin],
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expandResponse: false,
|
||||||
|
responseBodyMaxLines: 16,
|
||||||
|
doneButton: '<i class="material-icons">done</i>',
|
||||||
|
downloadButton: '<i class="material-icons">save_alt</i>',
|
||||||
|
copyButton: '<i class="material-icons">content_copy</i>',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
responseType() {
|
||||||
|
return (this.response.headers["content-type"] || "").split(";")[0].toLowerCase()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ToggleExpandResponse() {
|
||||||
|
this.expandResponse = !this.expandResponse
|
||||||
|
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
||||||
|
},
|
||||||
|
downloadResponse() {
|
||||||
|
const dataToWrite = this.responseBodyText
|
||||||
|
const file = new Blob([dataToWrite], { type: this.responseType })
|
||||||
|
const a = document.createElement("a")
|
||||||
|
const url = URL.createObjectURL(file)
|
||||||
|
a.href = url
|
||||||
|
// TODO get uri from meta
|
||||||
|
a.download = `response on ${Date()}`.replace(/\./g, "[dot]")
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("download_started"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(a)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
this.$refs.downloadResponse.innerHTML = this.downloadButton
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
copyResponse() {
|
||||||
|
this.$refs.copyResponse.innerHTML = this.doneButton
|
||||||
|
this.$toast.success(this.$t("copied_to_clipboard"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
|
const aux = document.createElement("textarea")
|
||||||
|
const copy = this.responseBodyText
|
||||||
|
aux.innerText = copy
|
||||||
|
document.body.appendChild(aux)
|
||||||
|
aux.select()
|
||||||
|
document.execCommand("copy")
|
||||||
|
document.body.removeChild(aux)
|
||||||
|
setTimeout(() => (this.$refs.copyResponse.innerHTML = this.copyButton), 1000)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
responseBodyText() {
|
||||||
|
return new TextDecoder("utf-8").decode(this.response.body)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
export default {
|
|
||||||
name: "textareaAutoHeight",
|
|
||||||
update({ scrollHeight, clientHeight, style }) {
|
|
||||||
if (scrollHeight !== clientHeight) {
|
|
||||||
style.minHeight = `${scrollHeight}px`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
8
helpers/lenses/htmlLens.js
Normal file
8
helpers/lenses/htmlLens.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const htmlLens = {
|
||||||
|
lensName: "HTML",
|
||||||
|
supportedContentTypes: ["text/html"],
|
||||||
|
renderer: "htmlres",
|
||||||
|
rendererImport: () => import("~/components/lenses/renderers/HTMLLensRenderer"),
|
||||||
|
}
|
||||||
|
|
||||||
|
export default htmlLens
|
||||||
16
helpers/lenses/imageLens.js
Normal file
16
helpers/lenses/imageLens.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
const imageLens = {
|
||||||
|
lensName: "Image",
|
||||||
|
supportedContentTypes: [
|
||||||
|
"image/gif",
|
||||||
|
"image/jpeg",
|
||||||
|
"image/png",
|
||||||
|
"image/bmp",
|
||||||
|
"image/svg+xml",
|
||||||
|
"image/x-icon",
|
||||||
|
"image/vnd.microsoft.icon",
|
||||||
|
],
|
||||||
|
renderer: "imageres",
|
||||||
|
rendererImport: () => import("~/components/lenses/renderers/ImageLensRenderer"),
|
||||||
|
}
|
||||||
|
|
||||||
|
export default imageLens
|
||||||
8
helpers/lenses/jsonLens.js
Normal file
8
helpers/lenses/jsonLens.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const jsonLens = {
|
||||||
|
lensName: "JSON",
|
||||||
|
supportedContentTypes: ["application/json", "application/hal+json", "application/vnd.api+json"],
|
||||||
|
renderer: "json",
|
||||||
|
rendererImport: () => import("~/components/lenses/renderers/JSONLensRenderer"),
|
||||||
|
}
|
||||||
|
|
||||||
|
export default jsonLens
|
||||||
37
helpers/lenses/lenses.js
Normal file
37
helpers/lenses/lenses.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import jsonLens from "./jsonLens"
|
||||||
|
import rawLens from "./rawLens"
|
||||||
|
import imageLens from "./imageLens"
|
||||||
|
import htmlLens from "./htmlLens"
|
||||||
|
import xmlLens from "./xmlLens"
|
||||||
|
|
||||||
|
const lenses = [jsonLens, imageLens, htmlLens, xmlLens, rawLens]
|
||||||
|
|
||||||
|
export function getSuitableLenses(response) {
|
||||||
|
const result = []
|
||||||
|
|
||||||
|
if (response && response.headers && response.headers["content-type"]) {
|
||||||
|
const properContentType = response.headers["content-type"].split(";")[0]
|
||||||
|
|
||||||
|
for (const lens of lenses) {
|
||||||
|
if (
|
||||||
|
lens.supportedContentTypes === null ||
|
||||||
|
lens.supportedContentTypes.includes(properContentType)
|
||||||
|
) {
|
||||||
|
result.push(lens)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We don't know the content type, so lets just add rawLens
|
||||||
|
result.push(rawLens)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLensRenderers() {
|
||||||
|
const response = {}
|
||||||
|
for (const lens of lenses) {
|
||||||
|
response[lens.renderer] = lens.rendererImport
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
8
helpers/lenses/rawLens.js
Normal file
8
helpers/lenses/rawLens.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const rawLens = {
|
||||||
|
lensName: "Raw",
|
||||||
|
supportedContentTypes: null,
|
||||||
|
renderer: "raw",
|
||||||
|
rendererImport: () => import("~/components/lenses/renderers/RawLensRenderer"),
|
||||||
|
}
|
||||||
|
|
||||||
|
export default rawLens
|
||||||
8
helpers/lenses/xmlLens.js
Normal file
8
helpers/lenses/xmlLens.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const xmlLens = {
|
||||||
|
lensName: "XML",
|
||||||
|
supportedContentTypes: ["application/xml", "image/svg+xml", "text/xml", "application/rss+xml"],
|
||||||
|
renderer: "xmlres",
|
||||||
|
rendererImport: () => import("~/components/lenses/renderers/XMLLensRenderer"),
|
||||||
|
}
|
||||||
|
|
||||||
|
export default xmlLens
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
|
import { decodeB64StringToArrayBuffer } from "../utils/b64"
|
||||||
|
|
||||||
let cancelSource = axios.CancelToken.source()
|
let cancelSource = axios.CancelToken.source()
|
||||||
|
|
||||||
@@ -13,11 +14,19 @@ const axiosWithProxy = async (req, { state }) => {
|
|||||||
try {
|
try {
|
||||||
const { data } = await axios.post(
|
const { data } = await axios.post(
|
||||||
state.postwoman.settings.PROXY_URL || "https://postwoman.apollosoftware.xyz/",
|
state.postwoman.settings.PROXY_URL || "https://postwoman.apollosoftware.xyz/",
|
||||||
req,
|
{
|
||||||
|
...req,
|
||||||
|
wantsBinary: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
cancelToken: cancelSource.token,
|
cancelToken: cancelSource.token,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (data.isBinary) {
|
||||||
|
data.data = decodeB64StringToArrayBuffer(data.data)
|
||||||
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Check if the throw is due to a cancellation
|
// Check if the throw is due to a cancellation
|
||||||
@@ -34,28 +43,9 @@ const axiosWithoutProxy = async (req, _store) => {
|
|||||||
const res = await axios({
|
const res = await axios({
|
||||||
...req,
|
...req,
|
||||||
cancelToken: cancelSource.token,
|
cancelToken: cancelSource.token,
|
||||||
transformResponse: [
|
responseType: "arraybuffer",
|
||||||
(data, headers) => {
|
|
||||||
// If the response has a JSON content type, try parsing it
|
|
||||||
if (
|
|
||||||
headers["content-type"] &&
|
|
||||||
(headers["content-type"].startsWith("application/json") ||
|
|
||||||
headers["content-type"].startsWith("application/vnd.api+json") ||
|
|
||||||
headers["content-type"].startsWith("application/hal+json"))
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const jsonData = JSON.parse(data)
|
|
||||||
return jsonData
|
|
||||||
} catch (e) {
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else return the string itself without any transformations
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return res
|
return res
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (axios.isCancel(e)) {
|
if (axios.isCancel(e)) {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { decodeB64StringToArrayBuffer } from "../utils/b64"
|
||||||
|
|
||||||
export const hasExtensionInstalled = () =>
|
export const hasExtensionInstalled = () =>
|
||||||
typeof window.__POSTWOMAN_EXTENSION_HOOK__ !== "undefined"
|
typeof window.__POSTWOMAN_EXTENSION_HOOK__ !== "undefined"
|
||||||
|
|
||||||
@@ -17,13 +19,24 @@ const extensionWithProxy = async (req, { state }) => {
|
|||||||
const { data } = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest({
|
const { data } = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest({
|
||||||
method: "post",
|
method: "post",
|
||||||
url: state.postwoman.settings.PROXY_URL || "https://postwoman.apollosoftware.xyz/",
|
url: state.postwoman.settings.PROXY_URL || "https://postwoman.apollosoftware.xyz/",
|
||||||
data: req,
|
data: {
|
||||||
|
...req,
|
||||||
|
wantsBinary: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (data.isBinary) {
|
||||||
|
data.data = decodeB64StringToArrayBuffer(data.data)
|
||||||
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
const extensionWithoutProxy = async (req, _store) => {
|
const extensionWithoutProxy = async (req, _store) => {
|
||||||
const res = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest(req)
|
const res = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest({
|
||||||
|
...req,
|
||||||
|
wantsBinary: true,
|
||||||
|
})
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
helpers/utils/b64.js
Normal file
31
helpers/utils/b64.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
export const decodeB64StringToArrayBuffer = (input) => {
|
||||||
|
const bytes = Math.floor((input.length / 4) * 3)
|
||||||
|
const ab = new ArrayBuffer(bytes)
|
||||||
|
const uarray = new Uint8Array(ab)
|
||||||
|
|
||||||
|
const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||||
|
|
||||||
|
let chr1, chr2, chr3
|
||||||
|
let enc1, enc2, enc3, enc4
|
||||||
|
let j = 0
|
||||||
|
|
||||||
|
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "")
|
||||||
|
|
||||||
|
for (let i = 0; i < bytes; i += 3) {
|
||||||
|
//get the 3 octets in 4 ASCII chars
|
||||||
|
enc1 = keyStr.indexOf(input.charAt(j++))
|
||||||
|
enc2 = keyStr.indexOf(input.charAt(j++))
|
||||||
|
enc3 = keyStr.indexOf(input.charAt(j++))
|
||||||
|
enc4 = keyStr.indexOf(input.charAt(j++))
|
||||||
|
|
||||||
|
chr1 = (enc1 << 2) | (enc2 >> 4)
|
||||||
|
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2)
|
||||||
|
chr3 = ((enc3 & 3) << 6) | enc4
|
||||||
|
|
||||||
|
uarray[i] = chr1
|
||||||
|
if (enc3 != 64) uarray[i + 1] = chr2
|
||||||
|
if (enc4 != 64) uarray[i + 2] = chr3
|
||||||
|
}
|
||||||
|
|
||||||
|
return ab
|
||||||
|
}
|
||||||
@@ -285,5 +285,7 @@
|
|||||||
"mqtt_topic_title": "Publish / Subscribe topic",
|
"mqtt_topic_title": "Publish / Subscribe topic",
|
||||||
"mqtt_publish": "Publish",
|
"mqtt_publish": "Publish",
|
||||||
"mqtt_subscribe": "Subscribe",
|
"mqtt_subscribe": "Subscribe",
|
||||||
"mqtt_unsubscribe": "Unsubscribe"
|
"mqtt_unsubscribe": "Unsubscribe",
|
||||||
|
"pre_request_script": "Pre-request Script",
|
||||||
|
"tests": "Tests"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
</pw-section>
|
</pw-section>
|
||||||
|
|
||||||
<pw-section class="orange" :label="$t('headers')" ref="headers">
|
<pw-section class="orange" :label="$t('headers')" ref="headers">
|
||||||
<ul>
|
<ul v-if="headers.length !== 0">
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
<label for="headerList">{{ $t("header_list") }}</label>
|
<label for="headerList">{{ $t("header_list") }}</label>
|
||||||
@@ -37,14 +37,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
|
||||||
id="headerList"
|
|
||||||
readonly
|
|
||||||
v-textarea-auto-height="headerString"
|
|
||||||
v-model="headerString"
|
|
||||||
:placeholder="$t('add_one_header')"
|
|
||||||
rows="1"
|
|
||||||
></textarea>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-for="(header, index) in headers" :key="`${header.value}_${index}`">
|
<ul v-for="(header, index) in headers" :key="`${header.value}_${index}`">
|
||||||
@@ -339,7 +331,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
import * as gql from "graphql"
|
import * as gql from "graphql"
|
||||||
import textareaAutoHeight from "~/directives/textareaAutoHeight"
|
|
||||||
import { commonHeaders } from "~/helpers/headers"
|
import { commonHeaders } from "~/helpers/headers"
|
||||||
import AceEditor from "~/components/ui/ace-editor"
|
import AceEditor from "~/components/ui/ace-editor"
|
||||||
import QueryEditor from "~/components/graphql/queryeditor"
|
import QueryEditor from "~/components/graphql/queryeditor"
|
||||||
@@ -347,9 +338,6 @@ import { getPlatformSpecialKey } from "~/helpers/platformutils"
|
|||||||
import { sendNetworkRequest } from "~/helpers/network"
|
import { sendNetworkRequest } from "~/helpers/network"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
directives: {
|
|
||||||
textareaAutoHeight,
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
"pw-section": () => import("~/components/layout/section"),
|
"pw-section": () => import("~/components/layout/section"),
|
||||||
"gql-field": () => import("~/components/graphql/field"),
|
"gql-field": () => import("~/components/graphql/field"),
|
||||||
|
|||||||
703
pages/index.vue
703
pages/index.vue
@@ -2,39 +2,6 @@
|
|||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="page-columns inner-left">
|
<div class="page-columns inner-left">
|
||||||
<pw-section v-if="showPreRequestScript" class="orange" label="Pre-Request" ref="preRequest">
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<div class="flex-wrap">
|
|
||||||
<label for="generatedCode">{{ $t("javascript_code") }}</label>
|
|
||||||
<div>
|
|
||||||
<a
|
|
||||||
href="https://github.com/liyasthomas/postwoman/wiki/Pre-Request-Scripts"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>
|
|
||||||
<button class="icon" v-tooltip="$t('wiki')">
|
|
||||||
<i class="material-icons">help_outline</i>
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Editor
|
|
||||||
v-model="preRequestScript"
|
|
||||||
:lang="'javascript'"
|
|
||||||
:options="{
|
|
||||||
maxLines: '16',
|
|
||||||
minLines: '8',
|
|
||||||
fontSize: '16px',
|
|
||||||
autoScrollEditorIntoView: true,
|
|
||||||
showPrintMargin: false,
|
|
||||||
useWorker: false,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</pw-section>
|
|
||||||
|
|
||||||
<pw-section class="blue" :label="$t('request')" ref="request">
|
<pw-section class="blue" :label="$t('request')" ref="request">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="shrink">
|
<li class="shrink">
|
||||||
@@ -297,15 +264,18 @@
|
|||||||
<div v-if="!rawInput">
|
<div v-if="!rawInput">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="reqParamList">{{ $t("parameter_list") }}</label>
|
<div class="flex-wrap">
|
||||||
<textarea
|
<label for="reqParamList">{{ $t("parameter_list") }}</label>
|
||||||
id="reqParamList"
|
<div>
|
||||||
readonly
|
<button
|
||||||
v-textarea-auto-height="rawRequestBody"
|
class="icon"
|
||||||
v-model="rawRequestBody"
|
@click="clearContent('bodyParams', $event)"
|
||||||
:placeholder="$t('add_one_parameter')"
|
v-tooltip.bottom="$t('clear')"
|
||||||
rows="1"
|
>
|
||||||
></textarea>
|
<i class="material-icons">clear_all</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-for="(param, index) in bodyParams" :key="index">
|
<ul v-for="(param, index) in bodyParams" :key="index">
|
||||||
@@ -364,7 +334,18 @@
|
|||||||
<div v-else>
|
<div v-else>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="rawBody">{{ $t("raw_request_body") }}</label>
|
<div class="flex-wrap">
|
||||||
|
<label for="rawBody">{{ $t("raw_request_body") }}</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="clearContent('rawParams', $event)"
|
||||||
|
v-tooltip.bottom="$t('clear')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">clear_all</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Editor
|
<Editor
|
||||||
v-model="rawParams"
|
v-model="rawParams"
|
||||||
:lang="rawInputEditorLang"
|
:lang="rawInputEditorLang"
|
||||||
@@ -402,40 +383,6 @@
|
|||||||
>
|
>
|
||||||
<i class="material-icons">code</i>
|
<i class="material-icons">code</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
class="icon"
|
|
||||||
id="preRequestScriptButton"
|
|
||||||
v-tooltip.bottom="{
|
|
||||||
content: !showPreRequestScript
|
|
||||||
? $t('show_prerequest_script')
|
|
||||||
: $t('hide_prerequest_script'),
|
|
||||||
}"
|
|
||||||
@click="showPreRequestScript = !showPreRequestScript"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="material-icons"
|
|
||||||
:class="showPreRequestScript"
|
|
||||||
v-if="!showPreRequestScript"
|
|
||||||
>
|
|
||||||
playlist_add
|
|
||||||
</i>
|
|
||||||
<i class="material-icons" :class="showPreRequestScript" v-else>
|
|
||||||
close
|
|
||||||
</i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon"
|
|
||||||
id="preRequestScriptButto"
|
|
||||||
v-tooltip.bottom="{
|
|
||||||
content: !testsEnabled ? 'Enable Tests' : 'Disable Tests',
|
|
||||||
}"
|
|
||||||
@click="testsEnabled = !testsEnabled"
|
|
||||||
>
|
|
||||||
<i class="material-icons" :class="testsEnabled" v-if="!testsEnabled">
|
|
||||||
playlist_add_check
|
|
||||||
</i>
|
|
||||||
<i class="material-icons" :class="testsEnabled" v-else>close</i>
|
|
||||||
</button>
|
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<button
|
<button
|
||||||
@@ -471,73 +418,105 @@
|
|||||||
</div>
|
</div>
|
||||||
</pw-section>
|
</pw-section>
|
||||||
|
|
||||||
<pw-section v-if="testsEnabled" class="orange" label="Tests" ref="postRequestTests">
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<div class="flex-wrap">
|
|
||||||
<label for="generatedCode">{{ $t("javascript_code") }}</label>
|
|
||||||
<div>
|
|
||||||
<a
|
|
||||||
href="https://github.com/liyasthomas/postwoman/wiki/Post-Requests-Tests"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>
|
|
||||||
<button class="icon" v-tooltip="$t('wiki')">
|
|
||||||
<i class="material-icons">help_outline</i>
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Editor
|
|
||||||
v-model="testScript"
|
|
||||||
:lang="'javascript'"
|
|
||||||
:options="{
|
|
||||||
maxLines: '16',
|
|
||||||
minLines: '8',
|
|
||||||
fontSize: '16px',
|
|
||||||
autoScrollEditorIntoView: true,
|
|
||||||
showPrintMargin: false,
|
|
||||||
useWorker: false,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<div v-if="testReports">
|
|
||||||
<div class="flex-wrap">
|
|
||||||
<label>Test Reports</label>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="icon"
|
|
||||||
@click="clearContent('tests', $event)"
|
|
||||||
v-tooltip.bottom="$t('clear')"
|
|
||||||
>
|
|
||||||
<i class="material-icons">clear_all</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-for="(testReport, index) in testReports" :key="index">
|
|
||||||
<div v-if="testReport.startBlock" class="info">
|
|
||||||
<h4>{{ testReport.startBlock }}</h4>
|
|
||||||
</div>
|
|
||||||
<p v-else-if="testReport.result" class="flex-wrap info">
|
|
||||||
<span :class="testReport.styles.class">
|
|
||||||
<i class="material-icons">
|
|
||||||
{{ testReport.styles.icon }}
|
|
||||||
</i>
|
|
||||||
<span> {{ testReport.result }}</span>
|
|
||||||
<span v-if="testReport.message">
|
|
||||||
<label> • {{ testReport.message }}</label>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
<div v-else-if="testReport.endBlock"><hr /></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</pw-section>
|
|
||||||
|
|
||||||
<section id="options">
|
<section id="options">
|
||||||
<tabs>
|
<tabs>
|
||||||
<tab :id="'authentication'" :label="$t('authentication')" :selected="true">
|
<tab
|
||||||
|
:id="'params'"
|
||||||
|
:label="
|
||||||
|
$t('parameters') + `${params.length !== 0 ? ' \xA0 • \xA0 ' + params.length : ''}`
|
||||||
|
"
|
||||||
|
:selected="true"
|
||||||
|
>
|
||||||
|
<pw-section class="pink" label="Parameters" ref="parameters">
|
||||||
|
<ul v-if="params.length !== 0">
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<label for="paramList">{{ $t("parameter_list") }}</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="clearContent('parameters', $event)"
|
||||||
|
v-tooltip.bottom="$t('clear')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">clear_all</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul v-for="(param, index) in params" :key="index">
|
||||||
|
<li>
|
||||||
|
<input
|
||||||
|
:placeholder="$t('parameter_count', { count: index + 1 })"
|
||||||
|
:name="'param' + index"
|
||||||
|
:value="param.key"
|
||||||
|
@change="
|
||||||
|
$store.commit('setKeyParams', {
|
||||||
|
index,
|
||||||
|
value: $event.target.value,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
autofocus
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input
|
||||||
|
:placeholder="$t('value_count', { count: index + 1 })"
|
||||||
|
:name="'value' + index"
|
||||||
|
:value="param.value"
|
||||||
|
@change="
|
||||||
|
$store.commit('setValueParams', {
|
||||||
|
index,
|
||||||
|
value: $event.target.value,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span class="select-wrapper">
|
||||||
|
<select
|
||||||
|
:name="'type' + index"
|
||||||
|
@change="
|
||||||
|
$store.commit('setTypeParams', {
|
||||||
|
index,
|
||||||
|
value: $event.target.value,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<option value="query" :selected="param.type === 'query'">{{
|
||||||
|
$t("query")
|
||||||
|
}}</option>
|
||||||
|
<option value="path" :selected="param.type === 'path'">{{
|
||||||
|
$t("path")
|
||||||
|
}}</option>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<div>
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="removeRequestParam(index)"
|
||||||
|
v-tooltip.bottom="$t('delete')"
|
||||||
|
id="param"
|
||||||
|
>
|
||||||
|
<i class="material-icons">delete</i>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="addRequestParam">
|
||||||
|
<i class="material-icons">add</i>
|
||||||
|
<span>{{ $t("add_new") }}</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</pw-section>
|
||||||
|
</tab>
|
||||||
|
|
||||||
|
<tab :id="'authentication'" :label="$t('authentication')">
|
||||||
<pw-section class="cyan" :label="$t('authentication')" ref="authentication">
|
<pw-section class="cyan" :label="$t('authentication')" ref="authentication">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@@ -741,9 +720,14 @@
|
|||||||
</pw-section>
|
</pw-section>
|
||||||
</tab>
|
</tab>
|
||||||
|
|
||||||
<tab :id="'headers'" :label="$t('headers')">
|
<tab
|
||||||
|
:id="'headers'"
|
||||||
|
:label="
|
||||||
|
$t('headers') + `${headers.length !== 0 ? ' \xA0 • \xA0 ' + headers.length : ''}`
|
||||||
|
"
|
||||||
|
>
|
||||||
<pw-section class="orange" label="Headers" ref="headers">
|
<pw-section class="orange" label="Headers" ref="headers">
|
||||||
<ul>
|
<ul v-if="headers.length !== 0">
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
<label for="headerList">{{ $t("header_list") }}</label>
|
<label for="headerList">{{ $t("header_list") }}</label>
|
||||||
@@ -757,14 +741,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
|
||||||
id="headerList"
|
|
||||||
readonly
|
|
||||||
v-textarea-auto-height="headerString"
|
|
||||||
v-model="headerString"
|
|
||||||
:placeholder="$t('add_one_header')"
|
|
||||||
rows="1"
|
|
||||||
></textarea>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-for="(header, index) in headers" :key="`${header.value}_${index}`">
|
<ul v-for="(header, index) in headers" :key="`${header.value}_${index}`">
|
||||||
@@ -822,119 +798,123 @@
|
|||||||
</pw-section>
|
</pw-section>
|
||||||
</tab>
|
</tab>
|
||||||
|
|
||||||
<tab :id="'params'" :label="$t('parameters')">
|
<tab :id="'pre_request_script'" :label="$t('pre_request_script')">
|
||||||
<pw-section class="pink" label="Parameters" ref="parameters">
|
<pw-section
|
||||||
|
v-if="showPreRequestScript"
|
||||||
|
class="orange"
|
||||||
|
:label="$t('pre_request_script')"
|
||||||
|
ref="preRequest"
|
||||||
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
<label for="paramList">{{ $t("parameter_list") }}</label>
|
<label for="generatedCode">{{ $t("javascript_code") }}</label>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<a
|
||||||
class="icon"
|
href="https://github.com/liyasthomas/postwoman/wiki/Pre-Request-Scripts"
|
||||||
@click="clearContent('parameters', $event)"
|
target="_blank"
|
||||||
v-tooltip.bottom="$t('clear')"
|
rel="noopener"
|
||||||
>
|
>
|
||||||
<i class="material-icons">clear_all</i>
|
<button class="icon" v-tooltip="$t('wiki')">
|
||||||
</button>
|
<i class="material-icons">help_outline</i>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<Editor
|
||||||
id="paramList"
|
v-model="preRequestScript"
|
||||||
readonly
|
:lang="'javascript'"
|
||||||
v-textarea-auto-height="queryString"
|
:options="{
|
||||||
v-model="queryString"
|
maxLines: '16',
|
||||||
:placeholder="$t('add_one_parameter')"
|
minLines: '8',
|
||||||
rows="1"
|
fontSize: '16px',
|
||||||
></textarea>
|
autoScrollEditorIntoView: true,
|
||||||
</li>
|
showPrintMargin: false,
|
||||||
</ul>
|
useWorker: false,
|
||||||
<ul v-for="(param, index) in params" :key="index">
|
}"
|
||||||
<li>
|
|
||||||
<input
|
|
||||||
:placeholder="$t('parameter_count', { count: index + 1 })"
|
|
||||||
:name="'param' + index"
|
|
||||||
:value="param.key"
|
|
||||||
@change="
|
|
||||||
$store.commit('setKeyParams', {
|
|
||||||
index,
|
|
||||||
value: $event.target.value,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
autofocus
|
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<input
|
|
||||||
:placeholder="$t('value_count', { count: index + 1 })"
|
|
||||||
:name="'value' + index"
|
|
||||||
:value="param.value"
|
|
||||||
@change="
|
|
||||||
$store.commit('setValueParams', {
|
|
||||||
index,
|
|
||||||
value: $event.target.value,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="select-wrapper">
|
|
||||||
<select
|
|
||||||
:name="'type' + index"
|
|
||||||
@change="
|
|
||||||
$store.commit('setTypeParams', {
|
|
||||||
index,
|
|
||||||
value: $event.target.value,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<option value="query" :selected="param.type === 'query'">{{
|
|
||||||
$t("query")
|
|
||||||
}}</option>
|
|
||||||
<option value="path" :selected="param.type === 'path'">{{
|
|
||||||
$t("path")
|
|
||||||
}}</option>
|
|
||||||
</select>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<div>
|
|
||||||
<li>
|
|
||||||
<button
|
|
||||||
class="icon"
|
|
||||||
@click="removeRequestParam(index)"
|
|
||||||
v-tooltip.bottom="$t('delete')"
|
|
||||||
id="param"
|
|
||||||
>
|
|
||||||
<i class="material-icons">delete</i>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</div>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
</pw-section>
|
||||||
|
</tab>
|
||||||
|
|
||||||
|
<tab
|
||||||
|
:id="'tests'"
|
||||||
|
:label="
|
||||||
|
$t('tests') +
|
||||||
|
`${testReports.length !== 0 ? ' \xA0 • \xA0 ' + testReports.length : ''}`
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<pw-section
|
||||||
|
v-if="testsEnabled"
|
||||||
|
class="orange"
|
||||||
|
:label="$t('tests')"
|
||||||
|
ref="postRequestTests"
|
||||||
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<button class="icon" @click="addRequestParam">
|
<div class="flex-wrap">
|
||||||
<i class="material-icons">add</i>
|
<label for="generatedCode">{{ $t("javascript_code") }}</label>
|
||||||
<span>{{ $t("add_new") }}</span>
|
<div>
|
||||||
</button>
|
<a
|
||||||
|
href="https://github.com/liyasthomas/postwoman/wiki/Post-Requests-Tests"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<button class="icon" v-tooltip="$t('wiki')">
|
||||||
|
<i class="material-icons">help_outline</i>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Editor
|
||||||
|
v-model="testScript"
|
||||||
|
:lang="'javascript'"
|
||||||
|
:options="{
|
||||||
|
maxLines: '16',
|
||||||
|
minLines: '8',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<div v-if="testReports.length !== 0">
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<label>Test Reports</label>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="icon"
|
||||||
|
@click="clearContent('tests', $event)"
|
||||||
|
v-tooltip.bottom="$t('clear')"
|
||||||
|
>
|
||||||
|
<i class="material-icons">clear_all</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-for="(testReport, index) in testReports" :key="index">
|
||||||
|
<div v-if="testReport.startBlock" class="info">
|
||||||
|
<h4>{{ testReport.startBlock }}</h4>
|
||||||
|
</div>
|
||||||
|
<p v-else-if="testReport.result" class="flex-wrap info">
|
||||||
|
<span :class="testReport.styles.class">
|
||||||
|
<i class="material-icons">
|
||||||
|
{{ testReport.styles.icon }}
|
||||||
|
</i>
|
||||||
|
<span> {{ testReport.result }}</span>
|
||||||
|
<span v-if="testReport.message">
|
||||||
|
<label> • {{ testReport.message }}</label>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<div v-else-if="testReport.endBlock"><hr /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</pw-section>
|
</pw-section>
|
||||||
</tab>
|
</tab>
|
||||||
</tabs>
|
</tabs>
|
||||||
|
|
||||||
<!-- <div class="flex-wrap">
|
|
||||||
<span></span>
|
|
||||||
<button
|
|
||||||
class="icon hide-on-small-screen"
|
|
||||||
@click="activeSidebar = !activeSidebar"
|
|
||||||
v-tooltip="{
|
|
||||||
content: activeSidebar ? 'Hide Sidebar' : 'Show Sidebar'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<i class="material-icons">
|
|
||||||
{{ activeSidebar ? "last_page" : "first_page" }}
|
|
||||||
</i>
|
|
||||||
</button>
|
|
||||||
</div> -->
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<pw-section class="purple" id="response" :label="$t('response')" ref="response">
|
<pw-section class="purple" id="response" :label="$t('response')" ref="response">
|
||||||
@@ -952,83 +932,9 @@
|
|||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-if="response.body">
|
<div v-if="response.body && response.body !== $t('loading')">
|
||||||
<li>
|
<response-renderer :response="response" />
|
||||||
<div class="flex-wrap">
|
</div>
|
||||||
<label for="body">{{ $t("response") }}</label>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="icon"
|
|
||||||
@click="ToggleExpandResponse"
|
|
||||||
ref="ToggleExpandResponse"
|
|
||||||
v-if="response.body"
|
|
||||||
v-tooltip="{
|
|
||||||
content: !expandResponse ? $t('expand_response') : $t('collapse_response'),
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<i class="material-icons">
|
|
||||||
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
|
||||||
</i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon"
|
|
||||||
@click="downloadResponse"
|
|
||||||
ref="downloadResponse"
|
|
||||||
v-if="response.body && canDownloadResponse"
|
|
||||||
v-tooltip="$t('download_file')"
|
|
||||||
>
|
|
||||||
<i class="material-icons">save_alt</i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon"
|
|
||||||
@click="copyResponse"
|
|
||||||
ref="copyResponse"
|
|
||||||
v-if="response.body"
|
|
||||||
v-tooltip="$t('copy_response')"
|
|
||||||
>
|
|
||||||
<i class="material-icons">content_copy</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="response-details-wrapper">
|
|
||||||
<Editor
|
|
||||||
:value="responseBodyText"
|
|
||||||
:lang="responseBodyType"
|
|
||||||
:options="{
|
|
||||||
maxLines: responseBodyMaxLines,
|
|
||||||
minLines: '16',
|
|
||||||
fontSize: '16px',
|
|
||||||
autoScrollEditorIntoView: true,
|
|
||||||
readOnly: true,
|
|
||||||
showPrintMargin: false,
|
|
||||||
useWorker: false,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<iframe
|
|
||||||
:class="{ hidden: !previewEnabled }"
|
|
||||||
class="covers-response"
|
|
||||||
ref="previewFrame"
|
|
||||||
src="about:blank"
|
|
||||||
></iframe>
|
|
||||||
</div>
|
|
||||||
<div class="align-right" v-if="response.body && responseType === 'text/html'">
|
|
||||||
<button class="icon" @click.prevent="togglePreview">
|
|
||||||
<i class="material-icons">
|
|
||||||
{{ !previewEnabled ? "visibility" : "visibility_off" }}
|
|
||||||
</i>
|
|
||||||
<span>
|
|
||||||
{{ previewEnabled ? $t("hide_preview") : $t("preview_html") }}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul v-for="(value, key) in response.headers" :key="key" class="response-headers">
|
|
||||||
<li>
|
|
||||||
<label :for="key">{{ key }}</label>
|
|
||||||
<input :id="key" :value="value" :name="key" readonly />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</pw-section>
|
</pw-section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1343,7 +1249,6 @@ import section from "~/components/layout/section"
|
|||||||
import url from "url"
|
import url from "url"
|
||||||
import querystring from "querystring"
|
import querystring from "querystring"
|
||||||
import { commonHeaders } from "~/helpers/headers"
|
import { commonHeaders } from "~/helpers/headers"
|
||||||
import textareaAutoHeight from "~/directives/textareaAutoHeight"
|
|
||||||
import parseCurlCommand from "~/assets/js/curlparser.js"
|
import parseCurlCommand from "~/assets/js/curlparser.js"
|
||||||
import getEnvironmentVariablesFromScript from "~/helpers/preRequest"
|
import getEnvironmentVariablesFromScript from "~/helpers/preRequest"
|
||||||
import runTestScriptWithVariables from "~/helpers/postwomanTesting"
|
import runTestScriptWithVariables from "~/helpers/postwomanTesting"
|
||||||
@@ -1408,9 +1313,6 @@ const parseHeaders = (xhr) => {
|
|||||||
export const findStatusGroup = (responseStatus) =>
|
export const findStatusGroup = (responseStatus) =>
|
||||||
statusCategories.find(({ statusCodeRegex }) => statusCodeRegex.test(responseStatus))
|
statusCategories.find(({ statusCodeRegex }) => statusCodeRegex.test(responseStatus))
|
||||||
export default {
|
export default {
|
||||||
directives: {
|
|
||||||
textareaAutoHeight,
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
"pw-section": section,
|
"pw-section": section,
|
||||||
"pw-toggle": () => import("~/components/ui/toggle"),
|
"pw-toggle": () => import("~/components/ui/toggle"),
|
||||||
@@ -1426,15 +1328,16 @@ export default {
|
|||||||
login: () => import("~/components/firebase/login"),
|
login: () => import("~/components/firebase/login"),
|
||||||
tabs: () => import("~/components/ui/tabs"),
|
tabs: () => import("~/components/ui/tabs"),
|
||||||
tab: () => import("~/components/ui/tab"),
|
tab: () => import("~/components/ui/tab"),
|
||||||
|
"response-renderer": () => import("~/components/lenses/ResponseBodyRenderer"),
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showModal: false,
|
showModal: false,
|
||||||
showPreRequestScript: false,
|
showPreRequestScript: true,
|
||||||
testsEnabled: false,
|
testsEnabled: true,
|
||||||
testScript: "// pw.expect('variable').toBe('value');",
|
testScript: "// pw.expect('variable').toBe('value');",
|
||||||
preRequestScript: "// pw.env.set('variable', 'value');",
|
preRequestScript: "// pw.env.set('variable', 'value');",
|
||||||
testReports: null,
|
testReports: [],
|
||||||
copyButton: '<i class="material-icons">content_copy</i>',
|
copyButton: '<i class="material-icons">content_copy</i>',
|
||||||
downloadButton: '<i class="material-icons">save_alt</i>',
|
downloadButton: '<i class="material-icons">save_alt</i>',
|
||||||
doneButton: '<i class="material-icons">done</i>',
|
doneButton: '<i class="material-icons">done</i>',
|
||||||
@@ -1445,9 +1348,7 @@ export default {
|
|||||||
body: "",
|
body: "",
|
||||||
},
|
},
|
||||||
validContentTypes: knownContentTypes,
|
validContentTypes: knownContentTypes,
|
||||||
previewEnabled: false,
|
|
||||||
paramsWatchEnabled: true,
|
paramsWatchEnabled: true,
|
||||||
expandResponse: false,
|
|
||||||
showTokenList: false,
|
showTokenList: false,
|
||||||
showTokenRequest: false,
|
showTokenRequest: false,
|
||||||
showTokenRequestList: false,
|
showTokenRequestList: false,
|
||||||
@@ -1455,9 +1356,6 @@ export default {
|
|||||||
showRequestModal: false,
|
showRequestModal: false,
|
||||||
editRequest: {},
|
editRequest: {},
|
||||||
urlExcludes: {},
|
urlExcludes: {},
|
||||||
responseBodyText: "",
|
|
||||||
responseBodyType: "text",
|
|
||||||
responseBodyMaxLines: 16,
|
|
||||||
activeSidebar: true,
|
activeSidebar: true,
|
||||||
fb,
|
fb,
|
||||||
customMethod: false,
|
customMethod: false,
|
||||||
@@ -1513,27 +1411,6 @@ export default {
|
|||||||
}
|
}
|
||||||
this.setRouteQueryState()
|
this.setRouteQueryState()
|
||||||
},
|
},
|
||||||
"response.body": function (val) {
|
|
||||||
if (
|
|
||||||
this.response.body === this.$t("waiting_send_req") ||
|
|
||||||
this.response.body === this.$t("loading")
|
|
||||||
) {
|
|
||||||
this.responseBodyText = this.response.body
|
|
||||||
this.responseBodyType = "text"
|
|
||||||
} else {
|
|
||||||
if (isJSONContentType(this.responseType)) {
|
|
||||||
this.responseBodyText = JSON.stringify(this.response.body, null, 2)
|
|
||||||
this.responseBodyType =
|
|
||||||
this.response.body.constructor.name === "Object" ? "json" : "json5"
|
|
||||||
} else if (this.responseType === "text/html") {
|
|
||||||
this.responseBodyText = this.response.body
|
|
||||||
this.responseBodyType = "html"
|
|
||||||
} else {
|
|
||||||
this.responseBodyText = this.response.body
|
|
||||||
this.responseBodyType = "text"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
params: {
|
params: {
|
||||||
handler: function (newValue) {
|
handler: function (newValue) {
|
||||||
if (!this.paramsWatchEnabled) {
|
if (!this.paramsWatchEnabled) {
|
||||||
@@ -1589,7 +1466,6 @@ export default {
|
|||||||
this.showRequestModal = true
|
this.showRequestModal = true
|
||||||
},
|
},
|
||||||
method() {
|
method() {
|
||||||
// this.$store.commit('setState', { 'value': ["POST", "PUT", "PATCH", "DELETE"].includes(this.method) ? 'application/json' : '', 'attribute': 'contentType' })
|
|
||||||
this.contentType = ["POST", "PUT", "PATCH", "DELETE"].includes(this.method)
|
this.contentType = ["POST", "PUT", "PATCH", "DELETE"].includes(this.method)
|
||||||
? "application/json"
|
? "application/json"
|
||||||
: ""
|
: ""
|
||||||
@@ -1609,14 +1485,6 @@ export default {
|
|||||||
isJSONContentType(this.contentType)
|
isJSONContentType(this.contentType)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
canDownloadResponse() {
|
|
||||||
return (
|
|
||||||
this.response &&
|
|
||||||
this.response.headers &&
|
|
||||||
this.response.headers["content-type"] &&
|
|
||||||
isJSONContentType(this.response.headers["content-type"])
|
|
||||||
)
|
|
||||||
},
|
|
||||||
uri: {
|
uri: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.request.uri ? this.$store.state.request.uri : this.url + this.path
|
return this.$store.state.request.uri ? this.$store.state.request.uri : this.url + this.path
|
||||||
@@ -2138,9 +2006,6 @@ export default {
|
|||||||
// Start showing the loading bar as soon as possible.
|
// Start showing the loading bar as soon as possible.
|
||||||
// The nuxt axios module will hide it when the request is made.
|
// The nuxt axios module will hide it when the request is made.
|
||||||
this.$nuxt.$loading.start()
|
this.$nuxt.$loading.start()
|
||||||
if (this.$refs.response.$el.classList.contains("hidden")) {
|
|
||||||
this.$refs.response.$el.classList.toggle("hidden")
|
|
||||||
}
|
|
||||||
this.previewEnabled = false
|
this.previewEnabled = false
|
||||||
this.response.status = this.$t("fetching")
|
this.response.status = this.$t("fetching")
|
||||||
this.response.body = this.$t("loading")
|
this.response.body = this.$t("loading")
|
||||||
@@ -2473,67 +2338,6 @@ export default {
|
|||||||
document.execCommand("copy")
|
document.execCommand("copy")
|
||||||
setTimeout(() => (this.$refs.copyRequestCode.innerHTML = this.copyButton), 1000)
|
setTimeout(() => (this.$refs.copyRequestCode.innerHTML = this.copyButton), 1000)
|
||||||
},
|
},
|
||||||
ToggleExpandResponse() {
|
|
||||||
this.expandResponse = !this.expandResponse
|
|
||||||
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
|
||||||
},
|
|
||||||
copyResponse() {
|
|
||||||
this.$refs.copyResponse.innerHTML = this.doneButton
|
|
||||||
this.$toast.success(this.$t("copied_to_clipboard"), {
|
|
||||||
icon: "done",
|
|
||||||
})
|
|
||||||
const aux = document.createElement("textarea")
|
|
||||||
const copy = isJSONContentType(this.responseType)
|
|
||||||
? JSON.stringify(this.response.body, null, 2)
|
|
||||||
: this.response.body
|
|
||||||
aux.innerText = copy
|
|
||||||
document.body.appendChild(aux)
|
|
||||||
aux.select()
|
|
||||||
document.execCommand("copy")
|
|
||||||
document.body.removeChild(aux)
|
|
||||||
setTimeout(() => (this.$refs.copyResponse.innerHTML = this.copyButton), 1000)
|
|
||||||
},
|
|
||||||
downloadResponse() {
|
|
||||||
const dataToWrite = JSON.stringify(this.response.body, null, 2)
|
|
||||||
const file = new Blob([dataToWrite], { type: this.responseType })
|
|
||||||
const a = document.createElement("a")
|
|
||||||
const url = URL.createObjectURL(file)
|
|
||||||
a.href = url
|
|
||||||
a.download = `${this.url + this.path} [${this.method}] on ${Date()}`.replace(/\./g, "[dot]")
|
|
||||||
document.body.appendChild(a)
|
|
||||||
a.click()
|
|
||||||
this.$refs.downloadResponse.innerHTML = this.doneButton
|
|
||||||
this.$toast.success(this.$t("download_started"), {
|
|
||||||
icon: "done",
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
document.body.removeChild(a)
|
|
||||||
window.URL.revokeObjectURL(url)
|
|
||||||
this.$refs.downloadResponse.innerHTML = this.downloadButton
|
|
||||||
}, 1000)
|
|
||||||
},
|
|
||||||
togglePreview() {
|
|
||||||
this.previewEnabled = !this.previewEnabled
|
|
||||||
if (this.previewEnabled) {
|
|
||||||
// If you want to add 'preview' support for other response types,
|
|
||||||
// just add them here.
|
|
||||||
if (this.responseType === "text/html") {
|
|
||||||
// If the preview already has that URL loaded, let's not bother re-loading it all.
|
|
||||||
if (this.$refs.previewFrame.getAttribute("data-previewing-url") === this.url) return
|
|
||||||
// Use DOMParser to parse document HTML.
|
|
||||||
const previewDocument = new DOMParser().parseFromString(
|
|
||||||
this.response.body,
|
|
||||||
this.responseType
|
|
||||||
)
|
|
||||||
// Inject <base href="..."> tag to head, to fix relative CSS/HTML paths.
|
|
||||||
previewDocument.head.innerHTML =
|
|
||||||
`<base href="${this.url}">` + previewDocument.head.innerHTML
|
|
||||||
// Finally, set the iframe source to the resulting HTML.
|
|
||||||
this.$refs.previewFrame.srcdoc = previewDocument.documentElement.outerHTML
|
|
||||||
this.$refs.previewFrame.setAttribute("data-previewing-url", this.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setRouteQueryState() {
|
setRouteQueryState() {
|
||||||
const flat = (key) => (this[key] !== "" ? `${key}=${this[key]}&` : "")
|
const flat = (key) => (this[key] !== "" ? `${key}=${this[key]}&` : "")
|
||||||
const deep = (key) => {
|
const deep = (key) => {
|
||||||
@@ -2629,6 +2433,15 @@ export default {
|
|||||||
},
|
},
|
||||||
clearContent(name, { target }) {
|
clearContent(name, { target }) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
|
case "bodyParams":
|
||||||
|
this.bodyParams = []
|
||||||
|
break
|
||||||
|
case "rawParams":
|
||||||
|
this.rawParams = "{}"
|
||||||
|
break
|
||||||
|
case "parameters":
|
||||||
|
this.params = []
|
||||||
|
break
|
||||||
case "auth":
|
case "auth":
|
||||||
this.auth = "None"
|
this.auth = "None"
|
||||||
this.httpUser = ""
|
this.httpUser = ""
|
||||||
@@ -2638,12 +2451,6 @@ export default {
|
|||||||
this.tokens = []
|
this.tokens = []
|
||||||
this.tokenReqs = []
|
this.tokenReqs = []
|
||||||
break
|
break
|
||||||
case "headers":
|
|
||||||
this.headers = []
|
|
||||||
break
|
|
||||||
case "parameters":
|
|
||||||
this.params = []
|
|
||||||
break
|
|
||||||
case "access_token":
|
case "access_token":
|
||||||
this.accessTokenName = ""
|
this.accessTokenName = ""
|
||||||
this.oidcDiscoveryUrl = ""
|
this.oidcDiscoveryUrl = ""
|
||||||
@@ -2652,28 +2459,29 @@ export default {
|
|||||||
this.clientId = ""
|
this.clientId = ""
|
||||||
this.scope = ""
|
this.scope = ""
|
||||||
break
|
break
|
||||||
|
case "headers":
|
||||||
|
this.headers = []
|
||||||
|
break
|
||||||
|
case "tests":
|
||||||
|
this.testReports = []
|
||||||
|
break
|
||||||
case "tokens":
|
case "tokens":
|
||||||
this.tokens = []
|
this.tokens = []
|
||||||
break
|
break
|
||||||
case "tokenReqs":
|
|
||||||
this.tokenReqs = []
|
|
||||||
case "tests":
|
|
||||||
this.testReports = null
|
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
this.method = "GET"
|
this.method = "GET"
|
||||||
this.url = "https://httpbin.org"
|
this.url = "https://httpbin.org"
|
||||||
this.path = "/get"
|
this.path = "/get"
|
||||||
this.uri = this.url + this.path
|
this.uri = this.url + this.path
|
||||||
this.label = ""
|
this.label = ""
|
||||||
|
this.bodyParams = []
|
||||||
|
this.rawParams = "{}"
|
||||||
|
this.files = []
|
||||||
|
this.params = []
|
||||||
this.auth = "None"
|
this.auth = "None"
|
||||||
this.httpUser = ""
|
this.httpUser = ""
|
||||||
this.httpPassword = ""
|
this.httpPassword = ""
|
||||||
this.bearerToken = ""
|
this.bearerToken = ""
|
||||||
this.headers = []
|
|
||||||
this.params = []
|
|
||||||
this.bodyParams = []
|
|
||||||
this.rawParams = ""
|
|
||||||
this.showTokenRequest = false
|
this.showTokenRequest = false
|
||||||
this.tokens = []
|
this.tokens = []
|
||||||
this.tokenReqs = []
|
this.tokenReqs = []
|
||||||
@@ -2683,7 +2491,8 @@ export default {
|
|||||||
this.accessTokenUrl = ""
|
this.accessTokenUrl = ""
|
||||||
this.clientId = ""
|
this.clientId = ""
|
||||||
this.scope = ""
|
this.scope = ""
|
||||||
this.files = []
|
this.headers = []
|
||||||
|
this.testReports = []
|
||||||
}
|
}
|
||||||
target.innerHTML = this.doneButton
|
target.innerHTML = this.doneButton
|
||||||
this.$toast.info(this.$t("cleared"), {
|
this.$toast.info(this.$t("cleared"), {
|
||||||
|
|||||||
@@ -14,21 +14,21 @@ describe("Authentication", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Enable username and password in URL with toggler", () => {
|
// it("Enable username and password in URL with toggler", () => {
|
||||||
cy.visit("/", { retryOnStatusCodeFailure: true })
|
// cy.visit("/", { retryOnStatusCodeFailure: true })
|
||||||
.get("#auth")
|
// .get("#auth")
|
||||||
.select("Basic Auth")
|
// .select("Basic Auth")
|
||||||
.get('input[name="http_basic_user"]', { timeout: 500 })
|
// .get('input[name="http_basic_user"]', { timeout: 500 })
|
||||||
.type("foo")
|
// .type("foo")
|
||||||
.get('input[name="http_basic_passwd"]', { timeout: 500 })
|
// .get('input[name="http_basic_passwd"]', { timeout: 500 })
|
||||||
.type("bar")
|
// .type("bar")
|
||||||
.url()
|
// .url()
|
||||||
.should("not.contain", "foo")
|
// .should("not.contain", "foo")
|
||||||
.should("not.contain", "bar")
|
// .should("not.contain", "bar")
|
||||||
.get(".toggle")
|
// .get(".toggle")
|
||||||
.click()
|
// .click()
|
||||||
.url()
|
// .url()
|
||||||
.should("contain", "foo")
|
// .should("contain", "foo")
|
||||||
.should("contain", "bar")
|
// .should("contain", "bar")
|
||||||
})
|
// })
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,15 +11,15 @@
|
|||||||
// })
|
// })
|
||||||
// })
|
// })
|
||||||
|
|
||||||
describe("Proxy enabled - external request", () => {
|
// describe("Proxy enabled - external request", () => {
|
||||||
it("Enable proxy and make a GET request to Postwoman API", () => {
|
// it("Enable proxy and make a GET request to Postwoman API", () => {
|
||||||
cy.enableProxy("/?url=https://postwoman.io&path=/.netlify/functions/api")
|
// cy.enableProxy("/?url=https://postwoman.io&path=/.netlify/functions/api")
|
||||||
.get("#send")
|
// .get("#send")
|
||||||
.click()
|
// .click()
|
||||||
.get("#response-details-wrapper", { timeout: 24000 })
|
// .get("#response-details-wrapper", { timeout: 24000 })
|
||||||
.should("be.visible")
|
// .should("be.visible")
|
||||||
.should(($wrapper) => {
|
// .should(($wrapper) => {
|
||||||
expect($wrapper).to.contain("Hello World")
|
// expect($wrapper).to.contain("Hello World")
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|||||||
Reference in New Issue
Block a user