Skip to content

Commit 0e2b5bb

Browse files
committed
Initial commit
0 parents  commit 0e2b5bb

34 files changed

+7238
-0
lines changed

.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
lib/
2+
node_modules/
3+
coverage/

.eslintrc.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
3+
parserOptions: {
4+
ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
5+
sourceType: 'module', // Allows for the use of imports
6+
},
7+
settings: {},
8+
extends: [
9+
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
10+
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
11+
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
12+
],
13+
rules: {
14+
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
15+
// e.g. '@typescript-eslint/explicit-function-return-type': 'off',
16+
'global-require': 'off',
17+
'import/no-extraneous-dependencies': 'off',
18+
'import/no-dynamic-require': 'off',
19+
'import/no-unresolved': 'off',
20+
'prettier/prettier': 'error',
21+
'@typescript-eslint/ban-ts-ignore': 'off',
22+
'@typescript-eslint/ban-ts-comment': 'off',
23+
},
24+
};

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/*
2+
coverage/*
3+
lib/*
4+
.vscode/

.npmignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
!/lib/*.js
3+
!types/
4+
!index.js
5+
!jest-preset.json
6+
!setup-files-after-env.js
7+
!setup.js
8+
!teardown.js
9+
!testEnvironment.js

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lib/
2+
node_modules/

.prettierrc.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
semi: true,
3+
trailingComma: 'all',
4+
singleQuote: true,
5+
printWidth: 120,
6+
tabWidth: 2,
7+
endOfLine: "auto"
8+
};

README.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Jest-Rest 🎪
2+
Jest Rest is a Rest API testing framework using Jest, Axios and Ajv.
3+
4+
Schema definition matching is done using AJV. (one of the fastest schema matcher).
5+
6+
### Highlights
7+
- **Debug** 🕵️ - Pause the tests to see what's happening in real-time.
8+
- **Logger** 📝- log request and response to the terminal for more debugging capability.
9+
- **Contract Tests** 🤝 - Perform contract testing / schema validation testing.
10+
- **Parallel tests** 🧪🧪 - Run parallel tests to speed-up testing.
11+
12+
<!-- [![Coverage Status](https://coveralls.io/repos/github/rupeshmore/jest-rest/badge.svg?branch=master)](https://coveralls.io/github/rupeshmore/jest-rest?branch=master) -->
13+
14+
15+
### Installation
16+
```bash
17+
npm install -D jest jest-rest-preset
18+
```
19+
20+
## Requirements
21+
22+
- Node.js >= 10.15.0
23+
- Jest >=25
24+
25+
## Usage
26+
27+
Update your Jest configuration, either:
28+
29+
- with `package.json`:
30+
31+
```json
32+
"jest": {
33+
"preset": "jest-rest-preset"
34+
}
35+
```
36+
37+
- with `jest.config.js`:
38+
39+
```javascript
40+
module.exports = {
41+
preset: "jest-rest-preset",
42+
...
43+
}
44+
```
45+
46+
**NOTE**: Be sure to remove any existing `testEnvironment` option from your Jest configuration. The `jest-rest-preset` preset needs to manage that option itself.
47+
48+
Use Jest-Rest in your tests:
49+
50+
- with `package.json`
51+
52+
```json
53+
{
54+
"scripts": {
55+
"test": "jest"
56+
}
57+
}
58+
```
59+
60+
```js
61+
describe('Get test', () => {
62+
63+
test('get', async () => {
64+
const get = await axios.get('https://httpbin.org/get', {headers: {token: "sometoken"}});
65+
await jestRest.debug();
66+
expect(get.status).toBe(200);
67+
});
68+
});
69+
```
70+
71+
## Configuration
72+
73+
You can specify a `jest-rest.config.js` or `jest-rest.config.json` at the root of the project. It should export a config object.
74+
75+
```javascript
76+
{
77+
78+
/*
79+
* Define all global config for axios here
80+
*
81+
* More info at https://github.com/axios/axios#request-config
82+
*/
83+
"axios": {},
84+
85+
/*
86+
* Define all global config for ajv here
87+
*
88+
* More info at https://ajv.js.org/#options
89+
* default option added is {"allError": true}
90+
*/
91+
"ajv": {}
92+
}
93+
```
94+
95+
96+
> Default jest timeout is 30 seconds
97+
98+
## Put the tests in debug mode
99+
100+
Jest Rest exposes a method `jestRest.debug()` that suspends test execution and allows to see what's going on.
101+
102+
```javascript
103+
await jestRest.debug();
104+
```
105+
106+
> This will work perfectly when the tests are run sequentially using the jests `--runInBand` option or only single test is run.
107+
108+
## Schema Validation
109+
110+
Jest-Rest extends the jest matcher to include schema validation using ajv.
111+
`toMatchSchema`
112+
113+
usage:
114+
```javascript
115+
const schema = {
116+
"properties": {
117+
"foo": { "type": "string" },
118+
"bar": { "type": "number", "maximum": 3 }
119+
}
120+
};
121+
test('schema validation', async () => {
122+
const data = {"foo": "abc", "bar": 2};
123+
expect(data).toMatchSchema(schema);
124+
});
125+
```
126+
127+
## Log request & response of axios
128+
129+
Use environment variable `logger` to log request and/ or response from axios to the console/terminal.
130+
131+
`logger="*request"` - To log axios request to console.
132+
`logger="*response"` - To log response to console.
133+
`logger="*info"` - To log request and response to console.
134+
`logger="*error"` - To log error request and / or response to console.
135+
136+
137+
usage:
138+
On Windows cmd
139+
```sh
140+
set logger=*request
141+
```
142+
143+
using powershell
144+
```sh
145+
$env:logger="*request, *response"
146+
```
147+
on Mac/linux
148+
```sh
149+
export logger="*request, *response"
150+
```
151+
152+
To disable logs, set an empty value `logger=""`.
153+
154+
## Usage with Typescript
155+
156+
Example Jest configuration in combination with [ts-jest](https://github.com/kulshekhar/ts-jest):
157+
158+
```javascript
159+
module.exports = {
160+
preset: 'jest-rest-preset',
161+
transform: {
162+
'^.+\\.ts$': 'ts-jest',
163+
},
164+
}
165+
```
166+
167+
Types are also available, which you can either use via directly in your test:
168+
169+
170+
or at your central `tsconfig.json` either via `types`:
171+
```json
172+
{
173+
"compilerOptions": {
174+
"types": ["jest-rest-preset", "@types/jest"]
175+
}
176+
}
177+
```
178+
179+
or via `files`:
180+
181+
```json
182+
{
183+
"files": [
184+
"@types/jest",
185+
"node_modules/jest-rest-preset/types/global.d.ts",
186+
]
187+
}
188+
```
189+
## HTML Reporters
190+
191+
There are multiple Html reporter plugin's available. Feel free to add as per your choice.
192+
- https://github.com/zaqqaz/jest-allure
193+
- https://github.com/dkelosky/jest-stare
194+
- https://github.com/Hazyzh/jest-html-reporters
195+
196+
197+
## Inspiration
198+
199+
Thanks to [jest-playwright](https://github.com/playwright-community/jest-playwright)
200+
201+
## License
202+
203+
MIT

examples/get.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/// <reference types="../types/global" />
2+
3+
describe('Get test', () => {
4+
test('get', async () => {
5+
const get = await axios.get('https://httpbin.org/get', { headers: { token: 'sometoken' } });
6+
await jestRest.debug();
7+
expect(get.status).toBe(200);
8+
});
9+
});

examples/post.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference types="../types/global" />
2+
3+
describe('Post test', () => {
4+
test('/post', async () => {
5+
const post = await axios.post('https://httpbin.org/post', { foo: 'bar' }).catch((err) => err.response);
6+
expect(post.status).toBe(200);
7+
});
8+
});

examples/schema.test.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/// <reference types="../types/global" />
2+
3+
import { toMatchSchema } from '../src/to-match-schema';
4+
5+
expect.extend({ toMatchSchema });
6+
7+
const schema = {
8+
host: 'cert',
9+
paths: {
10+
products: {
11+
get: {
12+
responses: {
13+
'401': {
14+
description: 'Problem with the client request',
15+
headers: {
16+
'x-correlator': {
17+
type: 'string',
18+
format: 'uuid',
19+
description: 'Correlation id',
20+
},
21+
},
22+
schema: {
23+
Unauthenticated: {
24+
allOf: [
25+
{
26+
type: 'object',
27+
required: ['code'],
28+
properties: {
29+
code: {
30+
type: 'string',
31+
enum: ['UNAUTHENTICATED'],
32+
default: 'UNAUTHENTICATED',
33+
description: 'Request not authenticated due to missing, invalid, or expired credentials.',
34+
},
35+
},
36+
},
37+
{
38+
type: 'object',
39+
required: ['message'],
40+
properties: {
41+
message: {
42+
type: 'string',
43+
description: 'A human readable description',
44+
},
45+
},
46+
},
47+
],
48+
},
49+
},
50+
examples: {
51+
'application/json': {
52+
code: 'UNAUTHENTICATED',
53+
message: 'Authentication error',
54+
},
55+
},
56+
},
57+
},
58+
},
59+
},
60+
},
61+
};
62+
63+
describe('Schema test', () => {
64+
const unAuthenticatedSchema = schema.paths.products.get.responses[401].schema.Unauthenticated;
65+
66+
test('fails', () => {
67+
const data = { code: 'AAA', message: 'token expired' };
68+
expect(() => expect(data).toMatchSchema(unAuthenticatedSchema)).toThrowError();
69+
});
70+
71+
test('passes', async () => {
72+
const data = { code: 'UNAUTHENTICATED', message: 'token expired' };
73+
expect(data).toMatchSchema(unAuthenticatedSchema);
74+
});
75+
});

0 commit comments

Comments
 (0)