ftmocks-utils 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +90 -22
- package/src/recorder.js +7 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
|
|
1
|
+
// import fs from 'fs';
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
// import path from 'path';
|
|
4
|
+
const path = require('path')
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
const nameToFolder = name => {
|
|
5
7
|
return name.replaceAll(' ', '_');
|
|
6
8
|
};
|
|
7
9
|
|
|
10
|
+
const getMockDir = config => {
|
|
11
|
+
if(!path.isAbsolute(config.MOCK_DIR)) {
|
|
12
|
+
return path.resolve( process.cwd(), config.MOCK_DIR);
|
|
13
|
+
}
|
|
14
|
+
return config.MOCK_DIR;
|
|
15
|
+
}
|
|
16
|
+
|
|
8
17
|
const areJsonEqual = (jsonObj1, jsonObj2) => {
|
|
9
18
|
// Check if both are objects and not null
|
|
10
19
|
if (typeof jsonObj1 === 'object' && jsonObj1 !== null &&
|
|
@@ -34,7 +43,7 @@ const areJsonEqual = (jsonObj1, jsonObj2) => {
|
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
const getDefaultMockDataFromConfig = (testConfig) => {
|
|
37
|
-
const defaultPath = path.join(testConfig
|
|
46
|
+
const defaultPath = path.join(getMockDir(testConfig), 'default.json');
|
|
38
47
|
|
|
39
48
|
try {
|
|
40
49
|
const defaultData = fs.readFileSync(defaultPath, 'utf8');
|
|
@@ -42,7 +51,7 @@ try {
|
|
|
42
51
|
|
|
43
52
|
// Read and attach mock data for each entry in parsedData
|
|
44
53
|
parsedData.forEach(entry => {
|
|
45
|
-
const mockFilePath = path.join(testConfig
|
|
54
|
+
const mockFilePath = path.join(getMockDir(testConfig), 'defaultMocks', `mock_${entry.id}.json`);;
|
|
46
55
|
try {
|
|
47
56
|
const mockData = fs.readFileSync(mockFilePath, 'utf8');
|
|
48
57
|
entry.fileContent = JSON.parse(mockData);
|
|
@@ -64,18 +73,18 @@ const loadMockDataFromConfig = (testConfig, _testName) => {
|
|
|
64
73
|
let testName = _testName;
|
|
65
74
|
if(!testName) {
|
|
66
75
|
// Read the test ID from mockServer.config.json
|
|
67
|
-
const configPath = path.join(testConfig
|
|
76
|
+
const configPath = path.join(getMockDir(testConfig), 'mockServer.config.json');
|
|
68
77
|
const configData = fs.readFileSync(configPath, 'utf8');
|
|
69
78
|
const config = JSON.parse(configData);
|
|
70
79
|
testName = config.testName;
|
|
71
80
|
}
|
|
72
81
|
// Read the tests from testConfig
|
|
73
|
-
const mocksPath = path.join(testConfig
|
|
82
|
+
const mocksPath = path.join(getMockDir(testConfig), `test_${nameToFolder(testName)}`, '_mock_list.json');
|
|
74
83
|
const mocksData = fs.readFileSync(mocksPath, 'utf8');
|
|
75
84
|
const mocks = JSON.parse(mocksData);
|
|
76
85
|
|
|
77
86
|
mocks.forEach(mock => {
|
|
78
|
-
const fileContent = JSON.parse(fs.readFileSync(path.join(testConfig
|
|
87
|
+
const fileContent = JSON.parse(fs.readFileSync(path.join(getMockDir(testConfig), `test_${nameToFolder(testName)}`, `mock_${mock.id}.json`), 'utf8'));
|
|
79
88
|
mock.fileContent = fileContent;
|
|
80
89
|
});
|
|
81
90
|
|
|
@@ -138,14 +147,20 @@ function compareMockToRequest(mock, req) {
|
|
|
138
147
|
}
|
|
139
148
|
|
|
140
149
|
function compareMockToFetchRequest(mock, fetchReq) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
method:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
try{
|
|
151
|
+
const mockURL = processURL(mock.fileContent.url, mock.fileContent.ignoreParams);
|
|
152
|
+
const reqURL = processURL(fetchReq.url, mock.fileContent.ignoreParams);
|
|
153
|
+
const postData = mock.fileContent.request?.postData?.text ? JSON.parse(mock.fileContent.request?.postData?.text) : mock.fileContent.request?.postData;
|
|
154
|
+
return isSameRequest({url: mockURL, method: mock.fileContent.method, postData}, {
|
|
155
|
+
method: fetchReq.options.method || 'GET',
|
|
156
|
+
postData: fetchReq.options.body?.length ? JSON.parse(fetchReq.options.body) : fetchReq.options.body,
|
|
157
|
+
url: reqURL,
|
|
158
|
+
});
|
|
159
|
+
} catch(e) {
|
|
160
|
+
console.debug('error at compareMockToFetchRequest', mock, fetchReq);
|
|
161
|
+
console.debug(e);
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
149
164
|
}
|
|
150
165
|
|
|
151
166
|
function getMatchingMockData({testMockData, defaultMockData, url, options, testConfig, testName}) {
|
|
@@ -160,7 +175,7 @@ function getMatchingMockData({testMockData, defaultMockData, url, options, testC
|
|
|
160
175
|
let foundMock = matchedMocks.find(mock => !mock.fileContent.served) ? matchedMocks.find(mock => !mock.fileContent.served) : matchedMocks[matchedMocks.length - 1];
|
|
161
176
|
// updating stats to mock file
|
|
162
177
|
if(foundMock) {
|
|
163
|
-
const mockFilePath = path.join(testConfig
|
|
178
|
+
const mockFilePath = path.join(getMockDir(testConfig), `test_${nameToFolder(testName)}`, `mock_${foundMock.id}.json`);
|
|
164
179
|
foundMock.fileContent.served = true;
|
|
165
180
|
fs.writeFileSync(mockFilePath, JSON.stringify(foundMock.fileContent, null, 2));
|
|
166
181
|
}
|
|
@@ -177,7 +192,7 @@ function getMatchingMockData({testMockData, defaultMockData, url, options, testC
|
|
|
177
192
|
async function resetAllMockStats({testMockData, testConfig, testName}) {
|
|
178
193
|
for(let i=0; i<testMockData.length; i++) {
|
|
179
194
|
const tmd = testMockData[i];
|
|
180
|
-
const mockFilePath = path.join(testConfig
|
|
195
|
+
const mockFilePath = path.join(getMockDir(testConfig), `test_${nameToFolder(testName)}`, `mock_${tmd.id}.json`);
|
|
181
196
|
tmd.fileContent.served = false;
|
|
182
197
|
await fs.writeFileSync(mockFilePath, JSON.stringify(tmd.fileContent, null, 2));
|
|
183
198
|
}
|
|
@@ -187,7 +202,9 @@ async function initiateJestFetch (jest, ftmocksConifg, testName) {
|
|
|
187
202
|
const testMockData = testName ? loadMockDataFromConfig(ftmocksConifg, testName) : [];
|
|
188
203
|
resetAllMockStats({testMockData, testConfig: ftmocksConifg, testName});
|
|
189
204
|
const defaultMockData = getDefaultMockDataFromConfig(ftmocksConifg);
|
|
205
|
+
console.debug('calling initiateJestFetch fetch');
|
|
190
206
|
global.fetch = jest.fn((url, options = {}) => {
|
|
207
|
+
console.debug('got fetch request', url, options);
|
|
191
208
|
let mockData = getMatchingMockData({testMockData, defaultMockData, url, options, testConfig: ftmocksConifg, testName});
|
|
192
209
|
if (mockData) {
|
|
193
210
|
console.debug('mocked', url, options);
|
|
@@ -209,6 +226,7 @@ async function initiateJestFetch (jest, ftmocksConifg, testName) {
|
|
|
209
226
|
});
|
|
210
227
|
});
|
|
211
228
|
|
|
229
|
+
console.debug('calling XMLHttpRequest fetch');
|
|
212
230
|
global.XMLHttpRequest = jest.fn(function () {
|
|
213
231
|
const xhrMock = {
|
|
214
232
|
open: jest.fn(),
|
|
@@ -281,6 +299,46 @@ async function initiateJestFetch (jest, ftmocksConifg, testName) {
|
|
|
281
299
|
return;
|
|
282
300
|
};
|
|
283
301
|
|
|
302
|
+
function initiateConsoleLogs(jest, ftmocksConifg, testName) {
|
|
303
|
+
const logsFile = path.join(getMockDir(ftmocksConifg), `test_${nameToFolder(testName)}`, '_logs.json');
|
|
304
|
+
let logs = [];
|
|
305
|
+
if(!fs.existsSync(logsFile)) {
|
|
306
|
+
fs.appendFileSync(logsFile, '[]', 'utf8');
|
|
307
|
+
} else {
|
|
308
|
+
fs.writeFileSync(logsFile, '[]', 'utf8');
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const writeToFile = (type, params) => {
|
|
312
|
+
const logMessage = params.join(' ') + '\n'; // Combine params into a string with spaces
|
|
313
|
+
logs.push({
|
|
314
|
+
type,
|
|
315
|
+
message: logMessage,
|
|
316
|
+
time: Date.now()
|
|
317
|
+
});
|
|
318
|
+
fs.writeFileSync(logsFile, JSON.stringify(logs, null, 2), 'utf8'); // Append the log message to the file
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
global.console = {
|
|
322
|
+
...console,
|
|
323
|
+
// uncomment to ignore a specific log level
|
|
324
|
+
log: jest.fn((...params) => {
|
|
325
|
+
writeToFile('log', params);
|
|
326
|
+
}),
|
|
327
|
+
debug: jest.fn((...params) => {
|
|
328
|
+
writeToFile('debug', params);
|
|
329
|
+
}),
|
|
330
|
+
info: jest.fn((...params) => {
|
|
331
|
+
writeToFile('info', params);
|
|
332
|
+
}),
|
|
333
|
+
warn: jest.fn((...params) => {
|
|
334
|
+
writeToFile('warn', params);
|
|
335
|
+
}),
|
|
336
|
+
error: jest.fn((...params) => {
|
|
337
|
+
writeToFile('error', params);
|
|
338
|
+
}),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
284
342
|
|
|
285
343
|
function countFilesInDirectory(directoryPath) {
|
|
286
344
|
return new Promise((resolve, reject) => {
|
|
@@ -301,8 +359,8 @@ function countFilesInDirectory(directoryPath) {
|
|
|
301
359
|
}
|
|
302
360
|
|
|
303
361
|
const saveSnap = async (html, ftmocksConifg, testName) => {
|
|
304
|
-
const snapFolder = path.join(ftmocksConifg
|
|
305
|
-
const snapTemplate = path.join(ftmocksConifg
|
|
362
|
+
const snapFolder = path.join(getMockDir(ftmocksConifg), `test_${nameToFolder(testName)}`, '_snaps');
|
|
363
|
+
const snapTemplate = path.join(getMockDir(ftmocksConifg), 'snap_template.html');
|
|
306
364
|
|
|
307
365
|
if (!fs.existsSync(snapFolder)) {
|
|
308
366
|
fs.mkdirSync(snapFolder);
|
|
@@ -318,10 +376,18 @@ const saveSnap = async (html, ftmocksConifg, testName) => {
|
|
|
318
376
|
};
|
|
319
377
|
|
|
320
378
|
const deleteAllSnaps = async (ftmocksConifg, testName) => {
|
|
321
|
-
const snapFolder = path.join(ftmocksConifg
|
|
379
|
+
const snapFolder = path.join(getMockDir(ftmocksConifg), `test_${nameToFolder(testName)}`, '_snaps');
|
|
322
380
|
fs.rmSync(snapFolder, { recursive: true, force: true });
|
|
323
381
|
};
|
|
324
382
|
|
|
383
|
+
const deleteAllLogs = async (ftmocksConifg, testName) => {
|
|
384
|
+
const mockDir = path.join(getMockDir(ftmocksConifg), `test_${nameToFolder(testName)}`);
|
|
385
|
+
const logFilePath = path.join(mockDir, `_logs.json`);
|
|
386
|
+
fs.rmSync(logFilePath, { recursive: true, force: true });
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
325
391
|
// Export functions as a module
|
|
326
392
|
module.exports = {
|
|
327
393
|
compareMockToRequest,
|
|
@@ -335,5 +401,7 @@ module.exports = {
|
|
|
335
401
|
resetAllMockStats,
|
|
336
402
|
initiateJestFetch,
|
|
337
403
|
saveSnap,
|
|
338
|
-
deleteAllSnaps
|
|
404
|
+
deleteAllSnaps,
|
|
405
|
+
deleteAllLogs,
|
|
406
|
+
initiateConsoleLogs
|
|
339
407
|
};
|
package/src/recorder.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
window.FTMOCKS_CONFIG = {
|
|
2
|
+
record_mocks_url: 'http://localhost:5000/api/v1/recordMockdata',
|
|
3
|
+
record_events_url: 'http://localhost:5000/api/v1/recordedEvents'
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
|
|
1
7
|
(function () {
|
|
2
8
|
// Intercept Fetch API
|
|
3
9
|
const originalFetch = window.fetch;
|
|
@@ -6,7 +12,7 @@
|
|
|
6
12
|
const addTrack = track => {
|
|
7
13
|
track.id = recordedTracks.length ? recordedTracks[recordedTracks.length - 1].id + 1 : 1;
|
|
8
14
|
track.time = new Date();
|
|
9
|
-
track.bodyHtml = document.documentElement.outerHTML.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');;
|
|
15
|
+
// track.bodyHtml = document.documentElement.outerHTML.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');;
|
|
10
16
|
|
|
11
17
|
fetch(window.FTMOCKS_CONFIG.record_events_url, {
|
|
12
18
|
method: 'POST',
|