ftmocks-utils 1.1.9 → 1.2.0
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 +106 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -2,6 +2,23 @@ const fs = require("fs");
|
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const { v4: uuidv4 } = require("uuid");
|
|
4
4
|
|
|
5
|
+
function charDifference(str1, str2) {
|
|
6
|
+
let count1 = {},
|
|
7
|
+
count2 = {};
|
|
8
|
+
|
|
9
|
+
for (let ch of str1) count1[ch] = (count1[ch] || 0) + 1;
|
|
10
|
+
for (let ch of str2) count2[ch] = (count2[ch] || 0) + 1;
|
|
11
|
+
|
|
12
|
+
let diff = 0;
|
|
13
|
+
let chars = new Set([...Object.keys(count1), ...Object.keys(count2)]);
|
|
14
|
+
|
|
15
|
+
for (let ch of chars) {
|
|
16
|
+
diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return diff;
|
|
20
|
+
}
|
|
21
|
+
|
|
5
22
|
const nameToFolder = (name) => {
|
|
6
23
|
return name.replaceAll(" ", "_");
|
|
7
24
|
};
|
|
@@ -102,7 +119,7 @@ const getDefaultMockDataFromConfig = (testConfig) => {
|
|
|
102
119
|
const mockData = fs.readFileSync(mockFilePath, "utf8");
|
|
103
120
|
entry.fileContent = JSON.parse(mockData);
|
|
104
121
|
} catch (error) {
|
|
105
|
-
console.error(`Error reading mock data for ${entry.
|
|
122
|
+
console.error(`Error reading mock data for ${entry.id}:`, error);
|
|
106
123
|
return entry; // Return the original entry if there's an error
|
|
107
124
|
}
|
|
108
125
|
});
|
|
@@ -188,6 +205,31 @@ const isSameRequest = (req1, req2) => {
|
|
|
188
205
|
return matched;
|
|
189
206
|
};
|
|
190
207
|
|
|
208
|
+
const getSameRequestRank = (req1, req2) => {
|
|
209
|
+
let rank = 1;
|
|
210
|
+
clearNulls(req1.postData);
|
|
211
|
+
clearNulls(req2.postData);
|
|
212
|
+
// Compare path names
|
|
213
|
+
const url1 = new URL(`http://domain.com${req1.url}`);
|
|
214
|
+
const url2 = new URL(`http://domain.com${req2.url}`);
|
|
215
|
+
if (url1.pathname !== url2.pathname) {
|
|
216
|
+
rank = 0;
|
|
217
|
+
} else if (url1.method?.toLowerCase() !== url2.method?.toLowerCase()) {
|
|
218
|
+
rank = 0;
|
|
219
|
+
} else {
|
|
220
|
+
// Compare query strings
|
|
221
|
+
const queryDiff = charDifference(url1.search || "", url2.search || "");
|
|
222
|
+
rank = rank + queryDiff;
|
|
223
|
+
// Compare post data
|
|
224
|
+
const charDiff = charDifference(
|
|
225
|
+
JSON.stringify(req1.postData || {}),
|
|
226
|
+
JSON.stringify(req2.postData || {})
|
|
227
|
+
);
|
|
228
|
+
rank = rank + charDiff;
|
|
229
|
+
}
|
|
230
|
+
return rank;
|
|
231
|
+
};
|
|
232
|
+
|
|
191
233
|
const processURL = (url, ignoreParams = []) => {
|
|
192
234
|
// Remove the hostname from the URL
|
|
193
235
|
const urlWithoutHost = url.replace(/^(https?:\/\/)?[^\/]+/, "");
|
|
@@ -248,6 +290,33 @@ function compareMockToFetchRequest(mock, fetchReq) {
|
|
|
248
290
|
return false;
|
|
249
291
|
}
|
|
250
292
|
|
|
293
|
+
function getCompareRankMockToFetchRequest(mock, fetchReq) {
|
|
294
|
+
try {
|
|
295
|
+
const mockURL = processURL(
|
|
296
|
+
mock.fileContent.url,
|
|
297
|
+
mock.fileContent.ignoreParams
|
|
298
|
+
);
|
|
299
|
+
const reqURL = processURL(fetchReq.url, mock.fileContent.ignoreParams);
|
|
300
|
+
const postData = mock.fileContent.request?.postData?.text
|
|
301
|
+
? JSON.parse(mock.fileContent.request?.postData?.text)
|
|
302
|
+
: mock.fileContent.request?.postData;
|
|
303
|
+
return getSameRequestRank(
|
|
304
|
+
{ url: mockURL, method: mock.fileContent.method, postData },
|
|
305
|
+
{
|
|
306
|
+
method: fetchReq.options.method || "GET",
|
|
307
|
+
postData: fetchReq.options.body?.length
|
|
308
|
+
? JSON.parse(fetchReq.options.body)
|
|
309
|
+
: fetchReq.options.body,
|
|
310
|
+
url: reqURL,
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
} catch (e) {
|
|
314
|
+
console.error("error at getCompareRankMockToFetchRequest", mock, fetchReq);
|
|
315
|
+
console.error(e);
|
|
316
|
+
}
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
|
|
251
320
|
function getMatchingMockData({
|
|
252
321
|
testMockData,
|
|
253
322
|
defaultMockData,
|
|
@@ -255,6 +324,7 @@ function getMatchingMockData({
|
|
|
255
324
|
options,
|
|
256
325
|
testConfig,
|
|
257
326
|
testName,
|
|
327
|
+
mode,
|
|
258
328
|
}) {
|
|
259
329
|
let served = false;
|
|
260
330
|
let matchedMocks =
|
|
@@ -290,6 +360,38 @@ function getMatchingMockData({
|
|
|
290
360
|
})
|
|
291
361
|
);
|
|
292
362
|
}
|
|
363
|
+
|
|
364
|
+
if (!foundMock && mode !== "strict") {
|
|
365
|
+
const mockRanks = {};
|
|
366
|
+
testMockData.forEach((tm) => {
|
|
367
|
+
const rank = getCompareRankMockToFetchRequest(tm, {
|
|
368
|
+
url,
|
|
369
|
+
options,
|
|
370
|
+
});
|
|
371
|
+
if (rank > 0) {
|
|
372
|
+
mockRanks[tm.id] = rank;
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
defaultMockData.forEach((tm) => {
|
|
376
|
+
const rank = getCompareRankMockToFetchRequest(tm, {
|
|
377
|
+
url,
|
|
378
|
+
options,
|
|
379
|
+
});
|
|
380
|
+
if (rank > 0) {
|
|
381
|
+
mockRanks[tm.id] = rank;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
// Sort by rank to find the best match
|
|
385
|
+
const sortedRanks = Object.entries(mockRanks).sort((a, b) => a[1] - b[1]);
|
|
386
|
+
if (sortedRanks.length > 0) {
|
|
387
|
+
const bestMockId = sortedRanks?.[0]?.[0];
|
|
388
|
+
if (bestMockId) {
|
|
389
|
+
foundMock = [...testMockData, ...defaultMockData].find(
|
|
390
|
+
(mock) => mock.id === bestMockId
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
293
395
|
return foundMock ? foundMock.fileContent : null;
|
|
294
396
|
}
|
|
295
397
|
|
|
@@ -320,6 +422,7 @@ async function initiatePlaywrightRoutes(
|
|
|
320
422
|
? loadMockDataFromConfig(ftmocksConifg, testName)
|
|
321
423
|
: [];
|
|
322
424
|
resetAllMockStats({ testMockData, testConfig: ftmocksConifg, testName });
|
|
425
|
+
const test = await getTestByName(ftmocksConifg, config.testName);
|
|
323
426
|
const defaultMockData = getDefaultMockDataFromConfig(ftmocksConifg);
|
|
324
427
|
console.debug("calling initiatePlaywrightRoutes fetch");
|
|
325
428
|
await page.route(mockPath, async (route, request) => {
|
|
@@ -346,6 +449,7 @@ async function initiatePlaywrightRoutes(
|
|
|
346
449
|
options,
|
|
347
450
|
testConfig: ftmocksConifg,
|
|
348
451
|
testName,
|
|
452
|
+
mode: test.mode || "loose",
|
|
349
453
|
});
|
|
350
454
|
if (mockData) {
|
|
351
455
|
console.debug("mocked", url, options);
|
|
@@ -903,6 +1007,7 @@ async function recordPlaywrightRoutes(
|
|
|
903
1007
|
|
|
904
1008
|
// Export functions as a module
|
|
905
1009
|
module.exports = {
|
|
1010
|
+
getTestByName,
|
|
906
1011
|
compareMockToRequest,
|
|
907
1012
|
processURL,
|
|
908
1013
|
isSameRequest,
|