Repository: pactumjs/pactum (js)

Issue:
Capture cookies as res.cookies in stores and returns 
**Is your feature request related to a problem? Please describe.**
Capture cookies as `res.cookies` in `stores` and `returns` 

**Describe the solution you'd like**
```js
stores('TOKEN', 'res.cookies.token')
```

Pull request:
feat: capture cookies with res.cookies and req.cookies in stores and returns
closes #174.

In addition, you can now add `cookies` to the interaction request and response:
```js
mock.addInteraction({
  request: {
    method: 'GET',
    path: '/api/hello',
    cookies: {
      lang: 'en',
    }
  },
  response: {
    status: 200,
    body: 'Hello, 👋',
    cookies: {
      token: 'xyz',
    }
  }
});
```

Patch:
diff --git a/src/exports/mock.d.ts b/src/exports/mock.d.ts
index 9c47116..dbf292d 100644
--- a/src/exports/mock.d.ts
+++ b/src/exports/mock.d.ts
@@ -10,6 +10,7 @@ export interface InteractionRequest {
   path: string;
   pathParams?: object;
   headers?: object;
+  cookies?: object;
   queryParams?: object;
   graphQL?: GraphQLRequest;
   body?: any;
@@ -19,11 +20,12 @@ export interface InteractionRequest {
 export interface InteractionResponse {
   status: number;
   headers?: object;
+  cookies?: object;
   body?: any;
   file?: string;
   fixedDelay?: number;
   randomDelay?: RandomDelay;
-  onCall?: OnCall
+  onCall?: OnCall;
 }
 
 export interface RandomDelay {
diff --git a/src/helpers/toss.helper.js b/src/helpers/toss.helper.js
index 7332858..ccbc575 100644
--- a/src/helpers/toss.helper.js
+++ b/src/helpers/toss.helper.js
@@ -1,3 +1,4 @@
+const lc = require('lightcookie');
 const jqy = require('json-query');
 
 const config = require('../config');
@@ -23,12 +24,26 @@ function getPathValueFromRequestResponse(path, request, response) {
   } else if (path.startsWith('req.headers')) {
     path = path.replace('req.headers', '');
     data = request.headers;
+  } else if (path.startsWith('req.cookies')) {
+    path = path.replace('req.cookies', '');
+    if (!request.headers) {
+      request.headers = {};
+    }
+    const cookies = lc.parse(request.headers['cookie']);
+    data = cookies;
   } else if (path.startsWith('req.body')) {
     path = path.replace('req.body', '');
     data = request.body;
   } else if (path.startsWith('res.headers')) {
     path = path.replace('res.headers', '');
     data = response.headers;
+  } else if (path.startsWith('res.cookies')) {
+    path = path.replace('res.cookies', '');
+    if (!response.headers) {
+      response.headers = {};
+    }
+    const cookies = lc.parse(response.headers['set-cookie']);
+    data = cookies;
   } else {
     path = path.replace('res.body', '');
     data = response.json;
diff --git a/src/models/Interaction.model.js b/src/models/Interaction.model.js
index 5c578c0..b95cbf1 100644
--- a/src/models/Interaction.model.js
+++ b/src/models/Interaction.model.js
@@ -1,3 +1,4 @@
+const lc = require('lightcookie');
 const { setMatchingRules, getValue } = require('pactum-matchers').utils;
 const processor = require('../helpers/dataProcessor');
 const helper = require('../helpers/helper');
@@ -119,6 +120,13 @@ class InteractionRequest {
       setMatchingRules(this.matchingRules, rawLowerCaseHeaders, '$.headers');
       this.headers = getValue(request.headers);
     }
+    if (request.cookies && typeof request.cookies === 'object') {
+      const cookie = lc.serialize(request.cookies);
+      if(!this.headers) {
+        this.headers = {};
+      }
+      this.headers['cookie'] = cookie;
+    }
     if (request.queryParams && typeof request.queryParams === 'object') {
       setMatchingRules(this.matchingRules, request.queryParams, '$.query');
       this.queryParams = getValue(request.queryParams);
@@ -161,6 +169,13 @@ class InteractionResponse {
     this.headers = getValue(response.headers);
     setMatchingRules(this.matchingRules, response.body, '$.body');
     this.body = getValue(response.body);
+    if(response.cookies) {
+      const cookie = lc.serialize(response.cookies);
+      if(!this.headers) {
+        this.headers = {};
+      }
+      this.headers['set-cookie'] = cookie;
+    }
     if (response.fixedDelay) {
       this.delay = new InteractionResponseDelay('FIXED', response.fixedDelay);
     } else if (response.randomDelay) {


Test patch:
diff --git a/test/component/returns.spec.js b/test/component/returns.spec.js
index 49769dc..829f80b 100644
--- a/test/component/returns.spec.js
+++ b/test/component/returns.spec.js
@@ -155,6 +155,39 @@ describe('Returns', () => {
     expect(response).equals('xyz');
   });
 
+  it('return response cookies', async () => {
+    const response = await pactum.spec()
+      .useInteraction({
+        request: {
+          method: 'GET',
+          path: '/api/users'
+        },
+        response: {
+          status: 200,
+          body: {
+            id: 1
+          },
+          cookies: {
+            token: 'xyz'
+          }
+        }
+      })
+      .get('http://localhost:9393/api/users')
+      .expectStatus(200)
+      .returns('res.cookies.token');
+    expect(response).equals('xyz');
+  });
+
+  it('return request cookies', async () => {
+    const response = await pactum.spec()
+      .useInteraction('default get')
+      .get('http://localhost:9393/default/get')
+      .withCookies('token', 'xyz')
+      .expectStatus(200)
+      .returns('req.cookies.token');
+    expect(response).equals('xyz');
+  });
+
   it('return request body', async () => {
     const response = await pactum.spec()
       .useInteraction('default post')
diff --git a/test/component/stores.spec.js b/test/component/stores.spec.js
index dfaeed4..45b7098 100644
--- a/test/component/stores.spec.js
+++ b/test/component/stores.spec.js
@@ -83,18 +83,25 @@ describe('Stores', () => {
               id: 2,
               name: 'Snow'
             }
-          ]
-        }
+          ],
+          cookies: {
+            token: 'xyz',
+          },
+        },
       })
       .get('http://localhost:9393/api/stores')
       .expectStatus(200)
       .stores('FirstUser', '[0]')
-      .stores('SecondUser', '[1]');
+      .stores('SecondUser', '[1]')
+      .stores('token', 'res.cookies.token');
     await pactum.spec()
       .useInteraction({
         request: {
           method: 'POST',
           path: '/api/stores',
+          cookies: {
+            token: 'xyz'
+          },
           body: {
             UserId: 1
           }
@@ -104,6 +111,7 @@ describe('Stores', () => {
         }
       })
       .post('http://localhost:9393/api/stores')
+      .withCookies('token','$S{token}')
       .withJson({
         UserId: '$S{FirstUser.id}'
       })