ftmocks-utils 1.2.2 → 1.2.5
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/common-utils.js +171 -0
- package/src/index.js +151 -208
package/package.json
CHANGED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
|
|
4
|
+
const charDifference = (str1, str2) => {
|
|
5
|
+
let count1 = {},
|
|
6
|
+
count2 = {};
|
|
7
|
+
|
|
8
|
+
for (let ch of str1) count1[ch] = (count1[ch] || 0) + 1;
|
|
9
|
+
for (let ch of str2) count2[ch] = (count2[ch] || 0) + 1;
|
|
10
|
+
|
|
11
|
+
let diff = 0;
|
|
12
|
+
let chars = new Set([...Object.keys(count1), ...Object.keys(count2)]);
|
|
13
|
+
|
|
14
|
+
for (let ch of chars) {
|
|
15
|
+
diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return diff;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const nameToFolder = (name) => {
|
|
22
|
+
return name.replaceAll(" ", "_");
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const getMockDir = (config) => {
|
|
26
|
+
if (!path.isAbsolute(config.MOCK_DIR)) {
|
|
27
|
+
return path.resolve(process.cwd(), config.MOCK_DIR);
|
|
28
|
+
}
|
|
29
|
+
return config.MOCK_DIR;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getFallbackDir = (config) => {
|
|
33
|
+
if (config.FALLBACK_DIR && !path.isAbsolute(config.FALLBACK_DIR)) {
|
|
34
|
+
return path.resolve(process.cwd(), config.FALLBACK_DIR);
|
|
35
|
+
}
|
|
36
|
+
return config.FALLBACK_DIR;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const capitalizeHeader = (header) => {
|
|
40
|
+
return header
|
|
41
|
+
.split("-")
|
|
42
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
43
|
+
.join("-");
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const capitalizeHeaders = (headers) => {
|
|
47
|
+
return Object.fromEntries(
|
|
48
|
+
Object.entries(headers).map(([key, value]) => [
|
|
49
|
+
capitalizeHeader(key),
|
|
50
|
+
value,
|
|
51
|
+
])
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const areJsonEqual = (jsonObj1, jsonObj2) => {
|
|
56
|
+
// Check if both are objects and not null
|
|
57
|
+
if (
|
|
58
|
+
typeof jsonObj1 === "object" &&
|
|
59
|
+
jsonObj1 !== null &&
|
|
60
|
+
typeof jsonObj2 === "object" &&
|
|
61
|
+
jsonObj2 !== null
|
|
62
|
+
) {
|
|
63
|
+
// Get the keys of both objects
|
|
64
|
+
const keys1 = Object.keys(jsonObj1);
|
|
65
|
+
const keys2 = Object.keys(jsonObj2);
|
|
66
|
+
|
|
67
|
+
// Check if the number of keys is different
|
|
68
|
+
if (keys1.length !== keys2.length) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Recursively check each key-value pair
|
|
73
|
+
for (let key of keys1) {
|
|
74
|
+
if (!keys2.includes(key) || !areJsonEqual(jsonObj1[key], jsonObj2[key])) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return true;
|
|
80
|
+
} else {
|
|
81
|
+
// For non-object types, use strict equality comparison
|
|
82
|
+
return jsonObj1 === jsonObj2;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const clearNulls = (postData) => {
|
|
87
|
+
Object.keys(postData || {}).forEach((key) => {
|
|
88
|
+
if (postData[key] === null) {
|
|
89
|
+
delete postData[key];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const processURL = (url, ignoreParams = []) => {
|
|
95
|
+
// Remove the hostname from the URL
|
|
96
|
+
const urlWithoutHost = url.replace(/^(https?:\/\/)?[^\/]+/, "");
|
|
97
|
+
const processedURL = new URL(`http://domain.com${urlWithoutHost}`);
|
|
98
|
+
const params = new URLSearchParams(processedURL.search);
|
|
99
|
+
if (ignoreParams?.length > 0) {
|
|
100
|
+
ignoreParams.forEach((ip) => {
|
|
101
|
+
params.delete(ip);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
params.sort();
|
|
105
|
+
return decodeURIComponent(`${processedURL.pathname}?${params}`);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const getHeaders = (headers) => {
|
|
109
|
+
let res = null;
|
|
110
|
+
try {
|
|
111
|
+
res = new Map([
|
|
112
|
+
...Object.entries(headers),
|
|
113
|
+
...Object.entries(capitalizeHeaders(headers)),
|
|
114
|
+
]);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
console.error("error at getHeaders", e);
|
|
117
|
+
res = new Map([
|
|
118
|
+
["Content-Type", "application/json"],
|
|
119
|
+
["content-type", "application/json"],
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
return Object.fromEntries(res);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
function countFilesInDirectory(directoryPath) {
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
fs.readdir(directoryPath, (err, files) => {
|
|
128
|
+
if (err) {
|
|
129
|
+
return reject(err); // Handle error
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Filter out directories and only count files
|
|
133
|
+
const fileCount = files.filter((file) => {
|
|
134
|
+
const filePath = path.join(directoryPath, file);
|
|
135
|
+
return fs.statSync(filePath).isFile();
|
|
136
|
+
}).length;
|
|
137
|
+
|
|
138
|
+
resolve(fileCount);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const getTestByName = async (ftmocksConifg, testName) => {
|
|
144
|
+
const testsPath = path.join(getMockDir(ftmocksConifg), "tests.json");
|
|
145
|
+
let tests = [];
|
|
146
|
+
try {
|
|
147
|
+
// Read existing tests
|
|
148
|
+
const testsData = fs.readFileSync(testsPath, "utf8");
|
|
149
|
+
tests = JSON.parse(testsData);
|
|
150
|
+
const etest = tests.find((tst) => tst.name === testName);
|
|
151
|
+
return etest;
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error(`\x1b[31mError reading tests.json:\x1b[0m`, error);
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
module.exports = {
|
|
159
|
+
charDifference,
|
|
160
|
+
nameToFolder,
|
|
161
|
+
getMockDir,
|
|
162
|
+
getFallbackDir,
|
|
163
|
+
capitalizeHeader,
|
|
164
|
+
capitalizeHeaders,
|
|
165
|
+
areJsonEqual,
|
|
166
|
+
clearNulls,
|
|
167
|
+
processURL,
|
|
168
|
+
getHeaders,
|
|
169
|
+
countFilesInDirectory,
|
|
170
|
+
getTestByName,
|
|
171
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,105 +1,18 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const { v4: uuidv4 } = require("uuid");
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return diff;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const nameToFolder = (name) => {
|
|
23
|
-
return name.replaceAll(" ", "_");
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const getMockDir = (config) => {
|
|
27
|
-
if (!path.isAbsolute(config.MOCK_DIR)) {
|
|
28
|
-
return path.resolve(process.cwd(), config.MOCK_DIR);
|
|
29
|
-
}
|
|
30
|
-
return config.MOCK_DIR;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const getFallbackDir = (config) => {
|
|
34
|
-
if (config.FALLBACK_DIR && !path.isAbsolute(config.FALLBACK_DIR)) {
|
|
35
|
-
return path.resolve(process.cwd(), config.FALLBACK_DIR);
|
|
36
|
-
}
|
|
37
|
-
return config.FALLBACK_DIR;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const capitalizeHeader = (header) => {
|
|
41
|
-
return header
|
|
42
|
-
.split("-")
|
|
43
|
-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
44
|
-
.join("-");
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const capitalizeHeaders = (headers) => {
|
|
48
|
-
return Object.fromEntries(
|
|
49
|
-
Object.entries(headers).map(([key, value]) => [
|
|
50
|
-
capitalizeHeader(key),
|
|
51
|
-
value,
|
|
52
|
-
])
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const getHeaders = (headers) => {
|
|
57
|
-
let res = null;
|
|
58
|
-
try {
|
|
59
|
-
res = new Map([
|
|
60
|
-
...Object.entries(headers),
|
|
61
|
-
...Object.entries(capitalizeHeaders(headers)),
|
|
62
|
-
]);
|
|
63
|
-
} catch (e) {
|
|
64
|
-
console.error("error at getHeaders", e);
|
|
65
|
-
res = new Map([
|
|
66
|
-
["Content-Type", "application/json"],
|
|
67
|
-
["content-type", "application/json"],
|
|
68
|
-
]);
|
|
69
|
-
}
|
|
70
|
-
return Object.fromEntries(res);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const areJsonEqual = (jsonObj1, jsonObj2) => {
|
|
74
|
-
// Check if both are objects and not null
|
|
75
|
-
if (
|
|
76
|
-
typeof jsonObj1 === "object" &&
|
|
77
|
-
jsonObj1 !== null &&
|
|
78
|
-
typeof jsonObj2 === "object" &&
|
|
79
|
-
jsonObj2 !== null
|
|
80
|
-
) {
|
|
81
|
-
// Get the keys of both objects
|
|
82
|
-
const keys1 = Object.keys(jsonObj1);
|
|
83
|
-
const keys2 = Object.keys(jsonObj2);
|
|
84
|
-
|
|
85
|
-
// Check if the number of keys is different
|
|
86
|
-
if (keys1.length !== keys2.length) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Recursively check each key-value pair
|
|
91
|
-
for (let key of keys1) {
|
|
92
|
-
if (!keys2.includes(key) || !areJsonEqual(jsonObj1[key], jsonObj2[key])) {
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return true;
|
|
98
|
-
} else {
|
|
99
|
-
// For non-object types, use strict equality comparison
|
|
100
|
-
return jsonObj1 === jsonObj2;
|
|
101
|
-
}
|
|
102
|
-
};
|
|
4
|
+
const {
|
|
5
|
+
charDifference,
|
|
6
|
+
nameToFolder,
|
|
7
|
+
getMockDir,
|
|
8
|
+
getFallbackDir,
|
|
9
|
+
areJsonEqual,
|
|
10
|
+
clearNulls,
|
|
11
|
+
processURL,
|
|
12
|
+
getHeaders,
|
|
13
|
+
countFilesInDirectory,
|
|
14
|
+
getTestByName,
|
|
15
|
+
} = require("./common-utils");
|
|
103
16
|
|
|
104
17
|
const getDefaultMockDataFromConfig = (testConfig) => {
|
|
105
18
|
const defaultPath = path.join(getMockDir(testConfig), "default.json");
|
|
@@ -174,14 +87,6 @@ const loadMockDataFromConfig = (testConfig, _testName) => {
|
|
|
174
87
|
}
|
|
175
88
|
};
|
|
176
89
|
|
|
177
|
-
const clearNulls = (postData) => {
|
|
178
|
-
Object.keys(postData || {}).forEach((key) => {
|
|
179
|
-
if (postData[key] === null) {
|
|
180
|
-
delete postData[key];
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
};
|
|
184
|
-
|
|
185
90
|
const isSameRequest = (req1, req2) => {
|
|
186
91
|
clearNulls(req1.postData);
|
|
187
92
|
clearNulls(req2.postData);
|
|
@@ -230,20 +135,6 @@ const getSameRequestRank = (req1, req2) => {
|
|
|
230
135
|
return rank;
|
|
231
136
|
};
|
|
232
137
|
|
|
233
|
-
const processURL = (url, ignoreParams = []) => {
|
|
234
|
-
// Remove the hostname from the URL
|
|
235
|
-
const urlWithoutHost = url.replace(/^(https?:\/\/)?[^\/]+/, "");
|
|
236
|
-
const processedURL = new URL(`http://domain.com${urlWithoutHost}`);
|
|
237
|
-
const params = new URLSearchParams(processedURL.search);
|
|
238
|
-
if (ignoreParams?.length > 0) {
|
|
239
|
-
ignoreParams.forEach((ip) => {
|
|
240
|
-
params.delete(ip);
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
params.sort();
|
|
244
|
-
return decodeURIComponent(`${processedURL.pathname}?${params}`);
|
|
245
|
-
};
|
|
246
|
-
|
|
247
138
|
function compareMockToRequest(mock, req) {
|
|
248
139
|
const mockURL = processURL(
|
|
249
140
|
mock.fileContent.url,
|
|
@@ -424,9 +315,13 @@ async function initiatePlaywrightRoutes(
|
|
|
424
315
|
resetAllMockStats({ testMockData, testConfig: ftmocksConifg, testName });
|
|
425
316
|
const test = await getTestByName(ftmocksConifg, testName);
|
|
426
317
|
const defaultMockData = getDefaultMockDataFromConfig(ftmocksConifg);
|
|
427
|
-
console.debug("
|
|
318
|
+
console.debug("\x1b[32mcalling initiatePlaywrightRoutes fetch\x1b[0m");
|
|
319
|
+
let firstUrl = null;
|
|
428
320
|
await page.route(mockPath, async (route, request) => {
|
|
429
321
|
const url = request.url();
|
|
322
|
+
if (!firstUrl) {
|
|
323
|
+
firstUrl = url;
|
|
324
|
+
}
|
|
430
325
|
const options = {
|
|
431
326
|
url,
|
|
432
327
|
method: request.method(),
|
|
@@ -436,12 +331,6 @@ async function initiatePlaywrightRoutes(
|
|
|
436
331
|
await route.fallback();
|
|
437
332
|
return;
|
|
438
333
|
}
|
|
439
|
-
console.debug(
|
|
440
|
-
"got fetch request",
|
|
441
|
-
request.method(),
|
|
442
|
-
request.url(),
|
|
443
|
-
request.postData()
|
|
444
|
-
);
|
|
445
334
|
let mockData = getMatchingMockData({
|
|
446
335
|
testMockData,
|
|
447
336
|
defaultMockData,
|
|
@@ -451,53 +340,140 @@ async function initiatePlaywrightRoutes(
|
|
|
451
340
|
testName,
|
|
452
341
|
mode: test.mode || "loose",
|
|
453
342
|
});
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
const json = {
|
|
459
|
-
status,
|
|
460
|
-
headers: getHeaders(headers),
|
|
461
|
-
body: content,
|
|
462
|
-
};
|
|
343
|
+
try {
|
|
344
|
+
if (mockData) {
|
|
345
|
+
const { content, headers, status, file } = mockData.response;
|
|
463
346
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
await route.fallback();
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
const urlObj = new URL(route.request().url());
|
|
473
|
-
const filePath = path.join(
|
|
474
|
-
fallbackDir,
|
|
475
|
-
urlObj.pathname === "/" || urlObj.pathname === ""
|
|
476
|
-
? ftmocksConifg.FALLBACK_DIR_INDEX_FILE || "index.html"
|
|
477
|
-
: urlObj.pathname
|
|
478
|
-
);
|
|
479
|
-
console.debug("serving file ", filePath);
|
|
480
|
-
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
|
|
481
|
-
const fileContent = fs.readFileSync(filePath);
|
|
482
|
-
const ext = path.extname(filePath);
|
|
483
|
-
const contentType =
|
|
484
|
-
{
|
|
485
|
-
".html": "text/html",
|
|
486
|
-
".css": "text/css",
|
|
487
|
-
".js": "application/javascript",
|
|
488
|
-
".json": "application/json",
|
|
489
|
-
".png": "image/png",
|
|
490
|
-
".jpg": "image/jpeg",
|
|
491
|
-
}[ext] || "application/octet-stream";
|
|
347
|
+
const json = {
|
|
348
|
+
status,
|
|
349
|
+
headers: getHeaders(headers),
|
|
350
|
+
body: content,
|
|
351
|
+
};
|
|
492
352
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
353
|
+
if (file) {
|
|
354
|
+
const filePath = path.join(
|
|
355
|
+
getMockDir(ftmocksConifg),
|
|
356
|
+
`test_${nameToFolder(testName)}`,
|
|
357
|
+
"_files",
|
|
358
|
+
file
|
|
359
|
+
);
|
|
360
|
+
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
|
|
361
|
+
const fileContent = fs.readFileSync(filePath);
|
|
362
|
+
json.body = fileContent;
|
|
363
|
+
|
|
364
|
+
console.debug(
|
|
365
|
+
"\x1b[32mresponse is a file, serving file\x1b[0m",
|
|
366
|
+
filePath,
|
|
367
|
+
url
|
|
368
|
+
);
|
|
369
|
+
await route.fulfill(json);
|
|
370
|
+
}
|
|
371
|
+
} else {
|
|
372
|
+
await route.fulfill(json);
|
|
373
|
+
}
|
|
498
374
|
} else {
|
|
499
|
-
|
|
375
|
+
const fallbackDir = getFallbackDir(ftmocksConifg);
|
|
376
|
+
if (!fallbackDir) {
|
|
377
|
+
await route.fallback();
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const urlObj = new URL(route.request().url());
|
|
381
|
+
let filePath = path.join(
|
|
382
|
+
fallbackDir,
|
|
383
|
+
urlObj.pathname === "/" || urlObj.pathname === ""
|
|
384
|
+
? ftmocksConifg.FALLBACK_DIR_INDEX_FILE || "index.html"
|
|
385
|
+
: urlObj.pathname
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
if (
|
|
389
|
+
!fs.existsSync(filePath) &&
|
|
390
|
+
!path.extname(filePath) &&
|
|
391
|
+
url === firstUrl
|
|
392
|
+
) {
|
|
393
|
+
filePath = path.join(
|
|
394
|
+
fallbackDir,
|
|
395
|
+
ftmocksConifg.FALLBACK_DIR_INDEX_FILE_FOR_STATUS_404 || "index.html"
|
|
396
|
+
);
|
|
397
|
+
console.debug(
|
|
398
|
+
"\x1b[32mserving file for status 404\x1b[0m",
|
|
399
|
+
filePath,
|
|
400
|
+
url
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
|
|
404
|
+
const fileContent = fs.readFileSync(filePath);
|
|
405
|
+
const ext = path.extname(filePath);
|
|
406
|
+
const contentType =
|
|
407
|
+
{
|
|
408
|
+
".html": "text/html",
|
|
409
|
+
".htm": "text/html",
|
|
410
|
+
".xhtml": "application/xhtml+xml",
|
|
411
|
+
".css": "text/css",
|
|
412
|
+
".js": "application/javascript",
|
|
413
|
+
".json": "application/json",
|
|
414
|
+
".png": "image/png",
|
|
415
|
+
".jpg": "image/jpeg",
|
|
416
|
+
".svg": "image/svg+xml",
|
|
417
|
+
".ico": "image/x-icon",
|
|
418
|
+
".webp": "image/webp",
|
|
419
|
+
".mp4": "video/mp4",
|
|
420
|
+
".mp3": "audio/mpeg",
|
|
421
|
+
".wav": "audio/wav",
|
|
422
|
+
".ogg": "audio/ogg",
|
|
423
|
+
".pdf": "application/pdf",
|
|
424
|
+
".doc": "application/msword",
|
|
425
|
+
".docx":
|
|
426
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
427
|
+
".xls": "application/vnd.ms-excel",
|
|
428
|
+
".xlsx":
|
|
429
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
430
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
431
|
+
".pptx":
|
|
432
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
433
|
+
".zip": "application/zip",
|
|
434
|
+
".rar": "application/x-rar-compressed",
|
|
435
|
+
".7z": "application/x-7z-compressed",
|
|
436
|
+
".tar": "application/x-tar",
|
|
437
|
+
".gz": "application/gzip",
|
|
438
|
+
".bz2": "application/x-bzip2",
|
|
439
|
+
".xz": "application/x-xz",
|
|
440
|
+
".exe": "application/x-msdownload",
|
|
441
|
+
".dll": "application/x-msdownload",
|
|
442
|
+
".so": "application/x-sharedlib",
|
|
443
|
+
".dylib": "application/x-dynamiclib",
|
|
444
|
+
".bin": "application/octet-stream",
|
|
445
|
+
".txt": "text/plain",
|
|
446
|
+
".csv": "text/csv",
|
|
447
|
+
".tsv": "text/tab-separated-values",
|
|
448
|
+
".xml": "application/xml",
|
|
449
|
+
".xsl": "application/xml",
|
|
450
|
+
".xslt": "application/xml",
|
|
451
|
+
".xlt": "application/xml",
|
|
452
|
+
".xltx": "application/xml",
|
|
453
|
+
".xltm": "application/xml",
|
|
454
|
+
".yaml": "text/yaml",
|
|
455
|
+
".yml": "text/yaml",
|
|
456
|
+
".toml": "text/toml",
|
|
457
|
+
".php": "application/x-httpd-php",
|
|
458
|
+
}[ext] || "application/octet-stream";
|
|
459
|
+
|
|
460
|
+
console.debug("\x1b[32mserving file\x1b[0m", filePath);
|
|
461
|
+
await route.fulfill({
|
|
462
|
+
body: fileContent,
|
|
463
|
+
headers: { "Content-Type": contentType },
|
|
464
|
+
});
|
|
465
|
+
} else {
|
|
466
|
+
console.debug("\x1b[31mmissing mock data, falling back\x1b[0m", url);
|
|
467
|
+
await route.fallback();
|
|
468
|
+
}
|
|
500
469
|
}
|
|
470
|
+
} catch (e) {
|
|
471
|
+
console.error(e);
|
|
472
|
+
console.error(
|
|
473
|
+
"\x1b[31merror at initiatePlaywrightRoutes\x1b[0m",
|
|
474
|
+
url,
|
|
475
|
+
options
|
|
476
|
+
);
|
|
501
477
|
}
|
|
502
478
|
});
|
|
503
479
|
}
|
|
@@ -657,24 +633,6 @@ function initiateConsoleLogs(jest, ftmocksConifg, testName) {
|
|
|
657
633
|
};
|
|
658
634
|
}
|
|
659
635
|
|
|
660
|
-
function countFilesInDirectory(directoryPath) {
|
|
661
|
-
return new Promise((resolve, reject) => {
|
|
662
|
-
fs.readdir(directoryPath, (err, files) => {
|
|
663
|
-
if (err) {
|
|
664
|
-
return reject(err); // Handle error
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Filter out directories and only count files
|
|
668
|
-
const fileCount = files.filter((file) => {
|
|
669
|
-
const filePath = path.join(directoryPath, file);
|
|
670
|
-
return fs.statSync(filePath).isFile();
|
|
671
|
-
}).length;
|
|
672
|
-
|
|
673
|
-
resolve(fileCount);
|
|
674
|
-
});
|
|
675
|
-
});
|
|
676
|
-
}
|
|
677
|
-
|
|
678
636
|
const saveSnap = async (html, ftmocksConifg, testName) => {
|
|
679
637
|
const snapFolder = path.join(
|
|
680
638
|
getMockDir(ftmocksConifg),
|
|
@@ -739,21 +697,6 @@ function initiateJestEventSnaps(jest, ftmocksConifg, testName) {
|
|
|
739
697
|
});
|
|
740
698
|
}
|
|
741
699
|
|
|
742
|
-
const getTestByName = async (ftmocksConifg, testName) => {
|
|
743
|
-
const testsPath = path.join(getMockDir(ftmocksConifg), "tests.json");
|
|
744
|
-
let tests = [];
|
|
745
|
-
try {
|
|
746
|
-
// Read existing tests
|
|
747
|
-
const testsData = fs.readFileSync(testsPath, "utf8");
|
|
748
|
-
tests = JSON.parse(testsData);
|
|
749
|
-
const etest = tests.find((tst) => tst.name === testName);
|
|
750
|
-
return etest;
|
|
751
|
-
} catch (error) {
|
|
752
|
-
console.error(`Error reading tests.json:`, error);
|
|
753
|
-
return null;
|
|
754
|
-
}
|
|
755
|
-
};
|
|
756
|
-
|
|
757
700
|
const createTest = async (ftmocksConifg, testName) => {
|
|
758
701
|
const testsPath = path.join(getMockDir(ftmocksConifg), "tests.json");
|
|
759
702
|
let tests = [];
|
|
@@ -776,13 +719,13 @@ const createTest = async (ftmocksConifg, testName) => {
|
|
|
776
719
|
const mockListFilePath = path.join(folderPath, "_mock_list.json");
|
|
777
720
|
fs.mkdir(folderPath, { recursive: true }, (err) => {
|
|
778
721
|
if (err) {
|
|
779
|
-
console.error("
|
|
722
|
+
console.error("\x1b[31mError creating directory:\x1b[0m", err);
|
|
780
723
|
} else {
|
|
781
|
-
console.log("
|
|
724
|
+
console.log("\x1b[32mDirectory created successfully!\x1b[0m");
|
|
782
725
|
}
|
|
783
726
|
});
|
|
784
727
|
await fs.appendFile(mockListFilePath, "[]", () => {
|
|
785
|
-
console.log("
|
|
728
|
+
console.log("\x1b[32mmock list file created successfully\x1b[0m");
|
|
786
729
|
});
|
|
787
730
|
|
|
788
731
|
return newTest;
|
|
@@ -790,7 +733,7 @@ const createTest = async (ftmocksConifg, testName) => {
|
|
|
790
733
|
throw "Test already exists";
|
|
791
734
|
}
|
|
792
735
|
} catch (error) {
|
|
793
|
-
console.error(
|
|
736
|
+
console.error(`\x1b[31mError reading tests.json:\x1b[0m`, error);
|
|
794
737
|
return null;
|
|
795
738
|
}
|
|
796
739
|
};
|