mirror of
https://github.com/usebruno/bruno.git
synced 2025-01-22 13:48:41 +01:00
Merge branch 'main' of github.com:usebruno/bruno
This commit is contained in:
commit
064281d438
1051
package-lock.json
generated
1051
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -70,7 +70,6 @@
|
||||
"strip-json-comments": "^5.0.1",
|
||||
"styled-components": "^5.3.3",
|
||||
"system": "^2.0.1",
|
||||
"tailwindcss": "^2.2.19",
|
||||
"url": "^0.11.3",
|
||||
"xml-formatter": "^3.5.0",
|
||||
"yargs-parser": "^21.1.1",
|
||||
@ -82,6 +81,7 @@
|
||||
"@babel/preset-env": "^7.16.4",
|
||||
"@babel/preset-react": "^7.16.0",
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"babel-loader": "^8.2.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.5.1",
|
||||
@ -89,8 +89,10 @@
|
||||
"html-loader": "^3.0.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"mini-css-extract-plugin": "^2.4.5",
|
||||
"postcss": "^8.4.35",
|
||||
"prettier": "^2.7.1",
|
||||
"style-loader": "^3.3.1",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"webpack": "^5.64.4",
|
||||
"webpack-cli": "^4.9.1"
|
||||
}
|
||||
|
6
packages/bruno-app/postcss.config.js
Normal file
6
packages/bruno-app/postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
};
|
@ -11,7 +11,7 @@ import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const Docs = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const docs = get(collection, 'root.docs', '');
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
@ -40,7 +40,7 @@ const Docs = ({ collection }) => {
|
||||
{isEditing ? (
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
value={docs || ''}
|
||||
onEdit={onEdit}
|
||||
onSave={onSave}
|
||||
|
@ -12,7 +12,7 @@ const Script = ({ collection }) => {
|
||||
const requestScript = get(collection, 'root.request.script.req', '');
|
||||
const responseScript = get(collection, 'root.request.script.res', '');
|
||||
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
|
||||
const onRequestScriptEdit = (value) => {
|
||||
@ -44,7 +44,7 @@ const Script = ({ collection }) => {
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
value={requestScript || ''}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
onEdit={onRequestScriptEdit}
|
||||
mode="javascript"
|
||||
onSave={handleSave}
|
||||
@ -56,7 +56,7 @@ const Script = ({ collection }) => {
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
value={responseScript || ''}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
onEdit={onResponseScriptEdit}
|
||||
mode="javascript"
|
||||
onSave={handleSave}
|
||||
|
@ -11,7 +11,7 @@ const Tests = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const tests = get(collection, 'root.request.tests', '');
|
||||
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
|
||||
const onEdit = (value) => {
|
||||
@ -30,7 +30,7 @@ const Tests = ({ collection }) => {
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
value={tests || ''}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
onEdit={onEdit}
|
||||
mode="javascript"
|
||||
onSave={handleSave}
|
||||
|
@ -11,7 +11,7 @@ import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const Documentation = ({ item, collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const docs = item.draft ? get(item, 'draft.request.docs') : get(item, 'request.docs');
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
@ -45,7 +45,7 @@ const Documentation = ({ item, collection }) => {
|
||||
{isEditing ? (
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
value={docs || ''}
|
||||
onEdit={onEdit}
|
||||
|
@ -10,7 +10,7 @@ import StyledWrapper from './StyledWrapper';
|
||||
const GraphQLVariables = ({ variables, item, collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
|
||||
const onEdit = (value) => {
|
||||
@ -31,7 +31,7 @@ const GraphQLVariables = ({ variables, item, collection }) => {
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
value={variables || ''}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
onEdit={onEdit}
|
||||
mode="javascript"
|
||||
|
@ -13,7 +13,7 @@ const RequestBody = ({ item, collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const body = item.draft ? get(item, 'draft.request.body') : get(item, 'request.body');
|
||||
const bodyMode = item.draft ? get(item, 'draft.request.body.mode') : get(item, 'request.body.mode');
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
|
||||
const onEdit = (value) => {
|
||||
@ -48,7 +48,7 @@ const RequestBody = ({ item, collection }) => {
|
||||
<StyledWrapper className="w-full">
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
value={bodyContent[bodyMode] || ''}
|
||||
onEdit={onEdit}
|
||||
|
@ -12,7 +12,7 @@ const Script = ({ item, collection }) => {
|
||||
const requestScript = item.draft ? get(item, 'draft.request.script.req') : get(item, 'request.script.req');
|
||||
const responseScript = item.draft ? get(item, 'draft.request.script.res') : get(item, 'request.script.res');
|
||||
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
|
||||
const onRequestScriptEdit = (value) => {
|
||||
@ -45,7 +45,7 @@ const Script = ({ item, collection }) => {
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
value={requestScript || ''}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
onEdit={onRequestScriptEdit}
|
||||
mode="javascript"
|
||||
@ -58,7 +58,7 @@ const Script = ({ item, collection }) => {
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
value={responseScript || ''}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
onEdit={onResponseScriptEdit}
|
||||
mode="javascript"
|
||||
|
@ -11,7 +11,7 @@ const Tests = ({ item, collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const tests = item.draft ? get(item, 'draft.request.tests') : get(item, 'request.tests');
|
||||
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
|
||||
const onEdit = (value) => {
|
||||
@ -32,7 +32,7 @@ const Tests = ({ item, collection }) => {
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
value={tests || ''}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
onEdit={onEdit}
|
||||
mode="javascript"
|
||||
|
@ -19,7 +19,7 @@ const QueryResultPreview = ({
|
||||
collection,
|
||||
mode,
|
||||
disableRunEventListener,
|
||||
storedTheme
|
||||
displayedTheme
|
||||
}) => {
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
const dispatch = useDispatch();
|
||||
@ -71,7 +71,7 @@ const QueryResultPreview = ({
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
onRun={onRun}
|
||||
value={formattedData}
|
||||
mode={mode}
|
||||
|
@ -51,7 +51,7 @@ const QueryResult = ({ item, collection, data, dataBuffer, width, disableRunEven
|
||||
const mode = getCodeMirrorModeBasedOnContentType(contentType, data);
|
||||
const [filter, setFilter] = useState(null);
|
||||
const formattedData = formatResponse(data, mode, filter);
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
|
||||
const debouncedResultFilterOnChange = debounce((e) => {
|
||||
setFilter(e.target.value);
|
||||
@ -132,7 +132,7 @@ const QueryResult = ({ item, collection, data, dataBuffer, width, disableRunEven
|
||||
collection={collection}
|
||||
allowedPreviewModes={allowedPreviewModes}
|
||||
disableRunEventListener={disableRunEventListener}
|
||||
storedTheme={storedTheme}
|
||||
displayedTheme={displayedTheme}
|
||||
/>
|
||||
{queryFilterEnabled && <QueryResultFilter onChange={debouncedResultFilterOnChange} mode={mode} />}
|
||||
</>
|
||||
|
@ -22,13 +22,23 @@ const getRelativePath = (fullPath, pathname) => {
|
||||
|
||||
export default function RunnerResults({ collection }) {
|
||||
const dispatch = useDispatch();
|
||||
const listWrapperRef = useRef();
|
||||
const [selectedItem, setSelectedItem] = useState(null);
|
||||
|
||||
// ref for the runner output body
|
||||
const runnerBodyRef = useRef();
|
||||
|
||||
const autoScrollRunnerBody = () => {
|
||||
if (runnerBodyRef?.current) {
|
||||
// mimicks the native terminal scroll style
|
||||
runnerBodyRef.current.scrollTo(0, 100000);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!collection.runnerResult) {
|
||||
setSelectedItem(null);
|
||||
}
|
||||
autoScrollRunnerBody();
|
||||
}, [collection, setSelectedItem]);
|
||||
|
||||
const collectionCopy = cloneDeep(collection);
|
||||
@ -67,11 +77,6 @@ export default function RunnerResults({ collection }) {
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
useEffect(() => {
|
||||
if (listWrapperRef.current) {
|
||||
listWrapperRef.current.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
|
||||
}
|
||||
}, [items]);
|
||||
const runCollection = () => {
|
||||
dispatch(runCollectionFolder(collection.uid, null, true));
|
||||
};
|
||||
@ -102,12 +107,11 @@ export default function RunnerResults({ collection }) {
|
||||
|
||||
if (!items || !items.length) {
|
||||
return (
|
||||
<StyledWrapper className="px-4">
|
||||
<StyledWrapper className="px-4 pb-4">
|
||||
<div className="font-medium mt-6 title flex items-center">
|
||||
Runner
|
||||
<IconRun size={20} strokeWidth={1.5} className="ml-2" />
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
You have <span className="font-medium">{totalRequestsInCollection}</span> requests in this collection.
|
||||
</div>
|
||||
@ -124,21 +128,25 @@ export default function RunnerResults({ collection }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledWrapper ref={listWrapperRef} className="px-4 pb-4 flex flex-grow flex-col relative">
|
||||
<div className="flex flex-row mt-6 mb-4">
|
||||
<div className="font-medium title flex items-center">
|
||||
<StyledWrapper className="px-4 pb-4 flex flex-grow flex-col relative">
|
||||
<div className="flex flex-row">
|
||||
<div className="font-medium my-6 title flex items-center">
|
||||
Runner
|
||||
<IconRun size={20} strokeWidth={1.5} className="ml-2" />
|
||||
</div>
|
||||
{runnerInfo.status !== 'ended' && runnerInfo.cancelTokenUid && (
|
||||
<button className="btn ml-6 btn-sm btn-danger" onClick={cancelExecution}>
|
||||
<button className="btn ml-6 my-4 btn-sm btn-danger" onClick={cancelExecution}>
|
||||
Cancel Execution
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-1">
|
||||
<div
|
||||
className="flex flex-col overflow-y-auto"
|
||||
ref={runnerBodyRef}
|
||||
style={{ height: 'calc(100vh - 12rem)', maxHeight: 'calc(100vh - 12rem)' }}
|
||||
>
|
||||
<div className="flex flex-col flex-1">
|
||||
<div className="py-2 font-medium test-summary">
|
||||
<div className="pb-2 font-medium test-summary">
|
||||
Total Requests: {items.length}, Passed: {passedRequests.length}, Failed: {failedRequests.length}
|
||||
</div>
|
||||
{items.map((item) => {
|
||||
|
@ -11,7 +11,7 @@ import { IconCopy } from '@tabler/icons';
|
||||
import { findCollectionByItemUid } from '../../../../../../../utils/collections/index';
|
||||
|
||||
const CodeView = ({ language, item }) => {
|
||||
const { storedTheme } = useTheme();
|
||||
const { displayedTheme } = useTheme();
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
const { target, client, language: lang } = language;
|
||||
const requestHeaders = item.draft ? get(item, 'draft.request.headers') : get(item, 'request.headers');
|
||||
@ -45,7 +45,7 @@ const CodeView = ({ language, item }) => {
|
||||
readOnly
|
||||
value={snippet}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
theme={storedTheme}
|
||||
theme={displayedTheme}
|
||||
mode={lang}
|
||||
/>
|
||||
</StyledWrapper>
|
||||
|
@ -159,6 +159,33 @@ const GlobalStyle = createGlobalStyle`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// scrollbar styling
|
||||
// the below media query target non-macos devices
|
||||
// (macos scrollbar styling is the ideal style reference)
|
||||
@media not all and (pointer: coarse) {
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: ${(props) => props.theme.scrollbar.color};
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: ${(props) => props.theme.scrollbar.color};
|
||||
border-radius: 14px;
|
||||
border: 3px solid ${(props) => props.theme.scrollbar.color};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// codemirror
|
||||
.CodeMirror {
|
||||
.cm-variable-valid {
|
||||
|
@ -10,7 +10,6 @@ import ErrorBoundary from './ErrorBoundary';
|
||||
|
||||
import '../styles/app.scss';
|
||||
import '../styles/globals.css';
|
||||
import 'tailwindcss/dist/tailwind.min.css';
|
||||
import 'codemirror/lib/codemirror.css';
|
||||
import 'graphiql/graphiql.min.css';
|
||||
import 'react-tooltip/dist/react-tooltip.css';
|
||||
|
@ -1,3 +1,7 @@
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
:root {
|
||||
--color-brand: #546de5;
|
||||
--color-text: rgb(52 52 52);
|
||||
|
@ -238,6 +238,10 @@ const darkTheme = {
|
||||
|
||||
plainGrid: {
|
||||
hoverBg: '#3D3D3D'
|
||||
},
|
||||
|
||||
scrollbar: {
|
||||
color: 'rgb(52 51 49)'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -242,6 +242,10 @@ const lightTheme = {
|
||||
|
||||
plainGrid: {
|
||||
hoverBg: '#f4f4f4'
|
||||
},
|
||||
|
||||
scrollbar: {
|
||||
color: 'rgb(152 151 149)'
|
||||
}
|
||||
};
|
||||
|
||||
|
8
packages/bruno-app/tailwind.config.js
Normal file
8
packages/bruno-app/tailwind.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
plugins: []
|
||||
};
|
@ -28,7 +28,7 @@ class EnvironmentSecretsStore {
|
||||
}
|
||||
|
||||
isValidValue(val) {
|
||||
return val && typeof val === 'string' && val.length > 0;
|
||||
return typeof val === 'string' && val.length >= 0;
|
||||
}
|
||||
|
||||
storeEnvSecrets(collectionPathname, environment) {
|
||||
|
@ -48,7 +48,7 @@ function safeStorageDecrypt(str) {
|
||||
}
|
||||
|
||||
function encryptString(str) {
|
||||
if (!str || typeof str !== 'string' || str.length === 0) {
|
||||
if (typeof str !== 'string') {
|
||||
throw new Error('Encrypt failed: invalid string');
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
"dependencies": {
|
||||
"@usebruno/query": "0.1.0",
|
||||
"ajv": "^8.12.0",
|
||||
"ajv-formats": "^2.1.1",
|
||||
"atob": "^2.1.2",
|
||||
"axios": "^1.5.1",
|
||||
"btoa": "^1.2.1",
|
||||
@ -28,7 +29,7 @@
|
||||
"moment": "^2.29.4",
|
||||
"nanoid": "3.3.4",
|
||||
"node-fetch": "2.*",
|
||||
"uuid": "^9.0.0",
|
||||
"node-vault": "^0.10.2"
|
||||
"node-vault": "^0.10.2",
|
||||
"uuid": "^9.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ const { cleanJson } = require('../utils');
|
||||
|
||||
// Inbuilt Library Support
|
||||
const ajv = require('ajv');
|
||||
const addFormats = require('ajv-formats');
|
||||
const atob = require('atob');
|
||||
const btoa = require('btoa');
|
||||
const lodash = require('lodash');
|
||||
@ -102,6 +103,7 @@ class ScriptRuntime {
|
||||
zlib,
|
||||
// 3rd party libs
|
||||
ajv,
|
||||
'ajv-formats': addFormats,
|
||||
atob,
|
||||
btoa,
|
||||
lodash,
|
||||
@ -194,6 +196,7 @@ class ScriptRuntime {
|
||||
zlib,
|
||||
// 3rd party libs
|
||||
ajv,
|
||||
'ajv-formats': addFormats,
|
||||
atob,
|
||||
btoa,
|
||||
lodash,
|
||||
|
@ -19,6 +19,7 @@ const { cleanJson } = require('../utils');
|
||||
|
||||
// Inbuilt Library Support
|
||||
const ajv = require('ajv');
|
||||
const addFormats = require('ajv-formats');
|
||||
const atob = require('atob');
|
||||
const btoa = require('btoa');
|
||||
const lodash = require('lodash');
|
||||
@ -120,6 +121,7 @@ class TestRuntime {
|
||||
zlib,
|
||||
// 3rd party libs
|
||||
ajv,
|
||||
'ajv-formats': addFormats,
|
||||
btoa,
|
||||
atob,
|
||||
lodash,
|
||||
|
@ -1,5 +1,6 @@
|
||||
const { describe, it, expect } = require('@jest/globals');
|
||||
const TestRuntime = require('../src/runtime/test-runtime');
|
||||
const ScriptRuntime = require('../src/runtime/script-runtime');
|
||||
|
||||
describe('runtime', () => {
|
||||
describe('test-runtime', () => {
|
||||
@ -49,5 +50,129 @@ describe('runtime', () => {
|
||||
{ description: 'async test', status: 'pass' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should have ajv and ajv-formats dependencies available', async () => {
|
||||
const testFile = `
|
||||
const Ajv = require('ajv');
|
||||
const addFormats = require("ajv-formats");
|
||||
const ajv = new Ajv();
|
||||
addFormats(ajv);
|
||||
|
||||
const schema = {
|
||||
type: 'string',
|
||||
format: 'date-time'
|
||||
};
|
||||
|
||||
const validate = ajv.compile(schema)
|
||||
|
||||
test('format valid', () => {
|
||||
const valid = validate(new Date().toISOString())
|
||||
expect(valid).to.be.true;
|
||||
})
|
||||
`;
|
||||
|
||||
const runtime = new TestRuntime();
|
||||
const result = await runtime.runTests(
|
||||
testFile,
|
||||
{ ...baseRequest },
|
||||
{ ...baseResponse },
|
||||
{},
|
||||
{},
|
||||
'.',
|
||||
null,
|
||||
process.env
|
||||
);
|
||||
expect(result.results.map((el) => ({ description: el.description, status: el.status }))).toEqual([
|
||||
{ description: 'format valid', status: 'pass' }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('script-runtime', () => {
|
||||
describe('run-request-script', () => {
|
||||
const baseRequest = {
|
||||
method: 'GET',
|
||||
url: 'http://localhost:3000/',
|
||||
headers: {},
|
||||
data: undefined
|
||||
};
|
||||
|
||||
it('should have ajv and ajv-formats dependencies available', async () => {
|
||||
const script = `
|
||||
const Ajv = require('ajv');
|
||||
const addFormats = require("ajv-formats");
|
||||
const ajv = new Ajv();
|
||||
addFormats(ajv);
|
||||
|
||||
const schema = {
|
||||
type: 'string',
|
||||
format: 'date-time'
|
||||
};
|
||||
|
||||
const validate = ajv.compile(schema)
|
||||
|
||||
bru.setVar('validation', validate(new Date().toISOString()))
|
||||
`;
|
||||
|
||||
const runtime = new ScriptRuntime();
|
||||
const result = await runtime.runRequestScript(script, { ...baseRequest }, {}, {}, '.', null, process.env);
|
||||
expect(result.collectionVariables.validation).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('run-response-script', () => {
|
||||
const baseRequest = {
|
||||
method: 'GET',
|
||||
url: 'http://localhost:3000/',
|
||||
headers: {},
|
||||
data: undefined
|
||||
};
|
||||
const baseResponse = {
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
data: [
|
||||
{
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
id: 2
|
||||
},
|
||||
{
|
||||
id: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
it('should have ajv and ajv-formats dependencies available', async () => {
|
||||
const script = `
|
||||
const Ajv = require('ajv');
|
||||
const addFormats = require("ajv-formats");
|
||||
const ajv = new Ajv();
|
||||
addFormats(ajv);
|
||||
|
||||
const schema = {
|
||||
type: 'string',
|
||||
format: 'date-time'
|
||||
};
|
||||
|
||||
const validate = ajv.compile(schema)
|
||||
|
||||
bru.setVar('validation', validate(new Date().toISOString()))
|
||||
`;
|
||||
|
||||
const runtime = new ScriptRuntime();
|
||||
const result = await runtime.runResponseScript(
|
||||
script,
|
||||
{ ...baseRequest },
|
||||
{ ...baseResponse },
|
||||
{},
|
||||
{},
|
||||
'.',
|
||||
null,
|
||||
process.env
|
||||
);
|
||||
expect(result.collectionVariables.validation).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user