ff-dom 1.0.18-beta.5 → 1.0.18
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/dist/index.browser.cjs +200 -199
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +200 -199
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cdn.js +200 -199
- package/dist/types/browser/browser/xpath.d.ts +5 -2
- package/dist/types/browser/utils/xpath.d.ts +4 -1
- package/dist/types/browser/utils/xpathHelpers.d.ts +2 -2
- package/dist/types/node/node/xpath.d.ts +1 -1
- package/dist/xpath.mjs +7 -6
- package/dist/xpath.mjs.map +1 -1
- package/package.json +1 -1
- package/src/node/xpath.ts +7 -6
- package/src/utils/getElementsFromHTML.ts +240 -240
- package/src/utils/xpath.ts +3 -1
- package/src/utils/xpathHelpers.ts +2 -2
package/dist/index.browser.js
CHANGED
|
@@ -865,9 +865,9 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget) => {
|
|
|
865
865
|
}
|
|
866
866
|
return xpaths1;
|
|
867
867
|
};
|
|
868
|
-
const parseXml = (xmlStr) => {
|
|
868
|
+
const parseXml = (xmlStr, type) => {
|
|
869
869
|
if (window.DOMParser) {
|
|
870
|
-
return new window.DOMParser().parseFromString(xmlStr,
|
|
870
|
+
return new window.DOMParser().parseFromString(xmlStr, type);
|
|
871
871
|
}
|
|
872
872
|
return null;
|
|
873
873
|
};
|
|
@@ -1080,7 +1080,7 @@ const getUniqueParentXpath = (domNode, docmt, node, isTarget, nodeXpath, isIndex
|
|
|
1080
1080
|
currentNode = currentNode.parentElement;
|
|
1081
1081
|
}
|
|
1082
1082
|
// Final constructed XPath
|
|
1083
|
-
const finalXPath = xpathParts.join("");
|
|
1083
|
+
const finalXPath = xpathParts.join("") + nodeXpath;
|
|
1084
1084
|
let count = getCountOfXPath(finalXPath, domNode, docmt);
|
|
1085
1085
|
if (count === 1) {
|
|
1086
1086
|
parentXpathCache.set(domNode, finalXPath); // Cache final result
|
|
@@ -1614,6 +1614,7 @@ const addAllXPathAttributes = (attributes, targetElemt, docmt, isIndex, isTarget
|
|
|
1614
1614
|
catch (error) {
|
|
1615
1615
|
console.log(error);
|
|
1616
1616
|
}
|
|
1617
|
+
return xpathData$1;
|
|
1617
1618
|
};
|
|
1618
1619
|
const parseDOM = (element, doc, isIndex, isTarget) => {
|
|
1619
1620
|
xpathData$1 = [];
|
|
@@ -2185,10 +2186,27 @@ const referenceXpath = {
|
|
|
2185
2186
|
getReferenceElementXpath,
|
|
2186
2187
|
};
|
|
2187
2188
|
|
|
2188
|
-
const getElementFromShadowRoot = (
|
|
2189
|
-
const shadowRoot = element.shadowRoot;
|
|
2190
|
-
if (shadowRoot && !selector.includes("dynamic")) {
|
|
2191
|
-
|
|
2189
|
+
const getElementFromShadowRoot = (el, selector) => {
|
|
2190
|
+
// const shadowRoot = (element as HTMLElement).shadowRoot;
|
|
2191
|
+
// if (shadowRoot && !selector.includes("dynamic")) {
|
|
2192
|
+
// return shadowRoot.querySelector(selector);
|
|
2193
|
+
// }
|
|
2194
|
+
const elements = Array.from(el.querySelectorAll('*'));
|
|
2195
|
+
try {
|
|
2196
|
+
for (let i = 0; i < elements.length; i++) {
|
|
2197
|
+
if (elements[i].shadowRoot) {
|
|
2198
|
+
const { shadowRoot } = elements[i];
|
|
2199
|
+
if (shadowRoot) {
|
|
2200
|
+
getElementFromShadowRoot(shadowRoot, selector);
|
|
2201
|
+
if (shadowRoot && !selector.includes("dynamic")) {
|
|
2202
|
+
return shadowRoot.querySelector(selector);
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
catch (error) {
|
|
2209
|
+
console.log(error);
|
|
2192
2210
|
}
|
|
2193
2211
|
return null;
|
|
2194
2212
|
};
|
|
@@ -2222,30 +2240,27 @@ const relations = [
|
|
|
2222
2240
|
"/preceding",
|
|
2223
2241
|
"/following",
|
|
2224
2242
|
];
|
|
2225
|
-
function getElementFromXPath(
|
|
2226
|
-
|
|
2227
|
-
const window = currentElement.ownerDocument.defaultView;
|
|
2243
|
+
function getElementFromXPath(docmt, xpath) {
|
|
2244
|
+
const window = docmt.defaultView;
|
|
2228
2245
|
if (!window)
|
|
2229
2246
|
return null;
|
|
2230
2247
|
const xpathEvaluator = new window.XPathEvaluator();
|
|
2231
|
-
const xpathResult = xpathEvaluator.evaluate(xpath,
|
|
2232
|
-
null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2248
|
+
const xpathResult = xpathEvaluator.evaluate(xpath, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2233
2249
|
return xpathResult.singleNodeValue;
|
|
2234
2250
|
}
|
|
2235
|
-
function checkReferenceElementIsValid(locator, relation,
|
|
2251
|
+
function checkReferenceElementIsValid(locator, relation, docmt) {
|
|
2236
2252
|
if (locator.includes(relation)) {
|
|
2237
2253
|
const locatotSplitArray = locator.split(relation);
|
|
2238
2254
|
const sourceLoc = locatotSplitArray[0].trim();
|
|
2239
|
-
|
|
2240
|
-
const window = currentElement.ownerDocument.defaultView;
|
|
2255
|
+
const window = docmt.defaultView;
|
|
2241
2256
|
if (!window)
|
|
2242
2257
|
return null;
|
|
2243
2258
|
if (!locator.includes("dynamic")) {
|
|
2244
2259
|
const xpathEvaluator = new window.XPathEvaluator();
|
|
2245
|
-
const xpathResult = xpathEvaluator.evaluate(sourceLoc,
|
|
2260
|
+
const xpathResult = xpathEvaluator.evaluate(sourceLoc, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2246
2261
|
const sourceElement = xpathResult.singleNodeValue;
|
|
2247
2262
|
if (sourceElement) {
|
|
2248
|
-
const xpathResultComplete = xpathEvaluator.evaluate(locator,
|
|
2263
|
+
const xpathResultComplete = xpathEvaluator.evaluate(locator, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2249
2264
|
const completeElement = xpathResultComplete.singleNodeValue;
|
|
2250
2265
|
let relativeXpath;
|
|
2251
2266
|
if (completeElement) {
|
|
@@ -2266,16 +2281,12 @@ function checkReferenceElementIsValid(locator, relation, tempDiv) {
|
|
|
2266
2281
|
return null;
|
|
2267
2282
|
}
|
|
2268
2283
|
const getElementsFromHTML = (record, docmt) => {
|
|
2269
|
-
const
|
|
2270
|
-
// global.SVGElement = document.defaultView?.SVGElement!;
|
|
2271
|
-
const tempDiv = document.createElement("div");
|
|
2272
|
-
const elementsToRemove = document.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
|
|
2284
|
+
const elementsToRemove = docmt.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
|
|
2273
2285
|
if (elementsToRemove) {
|
|
2274
2286
|
elementsToRemove.forEach((tag) => {
|
|
2275
2287
|
tag.remove();
|
|
2276
2288
|
});
|
|
2277
2289
|
}
|
|
2278
|
-
tempDiv.innerHTML = document.body.innerHTML;
|
|
2279
2290
|
const finalLocatorsSet = new Set();
|
|
2280
2291
|
let finalLocators = [];
|
|
2281
2292
|
function createLocator(base, overrides = {}) {
|
|
@@ -2349,209 +2360,199 @@ const getElementsFromHTML = (record, docmt) => {
|
|
|
2349
2360
|
if (record.isShared.includes("Y")) {
|
|
2350
2361
|
break locators;
|
|
2351
2362
|
}
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
targetElement = iframeDocument.querySelector(locator.value.slice(6));
|
|
2361
|
-
}
|
|
2363
|
+
try {
|
|
2364
|
+
let targetElement = null;
|
|
2365
|
+
if (locator.value.startsWith("iframe")) {
|
|
2366
|
+
const iframe = docmt.querySelector(locator.value);
|
|
2367
|
+
if (iframe) {
|
|
2368
|
+
const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
|
|
2369
|
+
if (iframeDocument) {
|
|
2370
|
+
targetElement = iframeDocument.querySelector(locator.value.slice(6));
|
|
2362
2371
|
}
|
|
2363
2372
|
}
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
});
|
|
2391
|
-
}
|
|
2392
|
-
}
|
|
2393
|
-
}
|
|
2394
|
-
else {
|
|
2395
|
-
targetElement = currentElement.querySelector(trimmedSelector);
|
|
2396
|
-
if (!targetElement) {
|
|
2397
|
-
targetElement = getElementFromShadowRoot(currentElement, trimmedSelector);
|
|
2398
|
-
}
|
|
2399
|
-
}
|
|
2400
|
-
if (!targetElement &&
|
|
2401
|
-
isSvg(currentElement) &&
|
|
2402
|
-
!locator.type.match("dynamic")) {
|
|
2403
|
-
targetElement = currentElement.querySelector(trimmedSelector);
|
|
2373
|
+
}
|
|
2374
|
+
else {
|
|
2375
|
+
const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
|
|
2376
|
+
for (const selector of selectors) {
|
|
2377
|
+
if (docmt) {
|
|
2378
|
+
const trimmedSelector = selector.trim();
|
|
2379
|
+
if (locator.name.includes("id") ||
|
|
2380
|
+
trimmedSelector.startsWith("#")) {
|
|
2381
|
+
targetElement = docmt.querySelector("#" + trimmedSelector);
|
|
2382
|
+
}
|
|
2383
|
+
else if (locator.name.includes("className") ||
|
|
2384
|
+
trimmedSelector.startsWith(".")) {
|
|
2385
|
+
targetElement = docmt.querySelector("." + trimmedSelector);
|
|
2386
|
+
}
|
|
2387
|
+
else if ((locator.name.includes("xpath") ||
|
|
2388
|
+
trimmedSelector.startsWith("//")) &&
|
|
2389
|
+
!locator.type.match("dynamic")) {
|
|
2390
|
+
const normalizedXPath = normalizeXPath(trimmedSelector);
|
|
2391
|
+
targetElement = getElementFromXPath(docmt, normalizedXPath);
|
|
2392
|
+
if (targetElement) {
|
|
2393
|
+
createLocator(locator, {
|
|
2394
|
+
value: trimmedSelector,
|
|
2395
|
+
isRecorded: String(locator.isRecorded).includes("N")
|
|
2396
|
+
? "N"
|
|
2397
|
+
: "Y",
|
|
2398
|
+
});
|
|
2404
2399
|
}
|
|
2405
|
-
currentElement = targetElement;
|
|
2406
2400
|
}
|
|
2407
2401
|
else {
|
|
2408
|
-
|
|
2409
|
-
|
|
2402
|
+
targetElement = docmt.querySelector(trimmedSelector);
|
|
2403
|
+
if (!targetElement) {
|
|
2404
|
+
targetElement = getElementFromShadowRoot(docmt.body, trimmedSelector);
|
|
2405
|
+
}
|
|
2410
2406
|
}
|
|
2411
2407
|
}
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
return finalLocatorsSet.has(key);
|
|
2416
|
-
};
|
|
2417
|
-
if (targetElement) {
|
|
2418
|
-
const idValue = getId(targetElement);
|
|
2419
|
-
if (idValue && !locatorExists("id", idValue)) {
|
|
2420
|
-
record.locators.forEach((loc) => {
|
|
2421
|
-
createLocator(loc, {
|
|
2422
|
-
name: "id",
|
|
2423
|
-
value: idValue,
|
|
2424
|
-
isRecorded: loc.value === idValue && loc.name === "id"
|
|
2425
|
-
? loc.isRecorded
|
|
2426
|
-
: "Y",
|
|
2427
|
-
isSelfHealed: loc.value === idValue && loc.name === "id"
|
|
2428
|
-
? loc.isSelfHealed
|
|
2429
|
-
: "Y",
|
|
2430
|
-
});
|
|
2431
|
-
});
|
|
2408
|
+
else {
|
|
2409
|
+
console.error("Element not found at:", selector);
|
|
2410
|
+
break;
|
|
2432
2411
|
}
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
const locatorExists = (name, value) => {
|
|
2415
|
+
const key = `${name}:${value}`;
|
|
2416
|
+
return finalLocatorsSet.has(key);
|
|
2417
|
+
};
|
|
2418
|
+
if (targetElement) {
|
|
2419
|
+
const idValue = getId(targetElement);
|
|
2420
|
+
if (idValue && !locatorExists("id", idValue)) {
|
|
2421
|
+
record.locators.forEach((loc) => {
|
|
2422
|
+
createLocator(loc, {
|
|
2423
|
+
name: "id",
|
|
2424
|
+
value: idValue,
|
|
2425
|
+
isRecorded: loc.value === idValue && loc.name === "id"
|
|
2426
|
+
? loc.isRecorded
|
|
2427
|
+
: "Y",
|
|
2428
|
+
isSelfHealed: loc.value === idValue && loc.name === "id"
|
|
2429
|
+
? loc.isSelfHealed
|
|
2430
|
+
: "Y",
|
|
2443
2431
|
});
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
isSelfHealed: loc.value === nameLocator && loc.name === "name"
|
|
2456
|
-
? loc.isSelfHealed
|
|
2457
|
-
: "Y",
|
|
2458
|
-
});
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2434
|
+
const textValue = getVisibleText(targetElement);
|
|
2435
|
+
if (textValue) {
|
|
2436
|
+
record.locators.forEach((loc) => {
|
|
2437
|
+
createLocator(loc, {
|
|
2438
|
+
name: "linkText",
|
|
2439
|
+
type: "static",
|
|
2440
|
+
value: textValue,
|
|
2441
|
+
isRecorded: loc.value === textValue ? loc.isRecorded : "Y",
|
|
2442
|
+
isSelfHealed: loc.value === textValue ? loc.isSelfHealed : "Y",
|
|
2459
2443
|
});
|
|
2460
|
-
}
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
});
|
|
2444
|
+
});
|
|
2445
|
+
}
|
|
2446
|
+
const nameLocator = getName(targetElement);
|
|
2447
|
+
if (nameLocator && !locatorExists("name", nameLocator)) {
|
|
2448
|
+
record.locators.forEach((loc) => {
|
|
2449
|
+
createLocator(loc, {
|
|
2450
|
+
name: "name",
|
|
2451
|
+
type: "static",
|
|
2452
|
+
value: nameLocator,
|
|
2453
|
+
isRecorded: loc.value === nameLocator && loc.name === "name"
|
|
2454
|
+
? loc.isRecorded
|
|
2455
|
+
: "Y",
|
|
2456
|
+
isSelfHealed: loc.value === nameLocator && loc.name === "name"
|
|
2457
|
+
? loc.isSelfHealed
|
|
2458
|
+
: "Y",
|
|
2476
2459
|
});
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2462
|
+
const classValue = getClassName(targetElement);
|
|
2463
|
+
if (classValue &&
|
|
2464
|
+
classValue.trim() !== "" &&
|
|
2465
|
+
!locatorExists("className", classValue)) {
|
|
2479
2466
|
record.locators.forEach((loc) => {
|
|
2480
2467
|
createLocator(loc, {
|
|
2481
|
-
name:
|
|
2482
|
-
value:
|
|
2483
|
-
isRecorded:
|
|
2468
|
+
name: "className",
|
|
2469
|
+
value: classValue,
|
|
2470
|
+
isRecorded: loc.value === classValue && loc.name === "className"
|
|
2484
2471
|
? loc.isRecorded
|
|
2485
2472
|
: "Y",
|
|
2486
|
-
isSelfHealed:
|
|
2473
|
+
isSelfHealed: loc.value === classValue && loc.name === "className"
|
|
2487
2474
|
? loc.isSelfHealed
|
|
2488
2475
|
: "Y",
|
|
2489
2476
|
});
|
|
2490
2477
|
});
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2478
|
+
}
|
|
2479
|
+
const xpathResults = parseDOM(targetElement, docmt, false, true);
|
|
2480
|
+
xpathResults.forEach((result) => {
|
|
2481
|
+
const fnValue = result.value;
|
|
2482
|
+
if (fnValue && !locatorExists(result.key.replace('xpath by', '').trim(), fnValue)) {
|
|
2483
|
+
record.locators.forEach((loc) => {
|
|
2484
|
+
createLocator(loc, {
|
|
2485
|
+
name: 'xpath',
|
|
2486
|
+
value: fnValue,
|
|
2487
|
+
isRecorded: loc.value === fnValue ? loc.isRecorded : 'Y',
|
|
2488
|
+
isSelfHealed: loc.value === fnValue ? loc.isSelfHealed : 'Y',
|
|
2489
|
+
});
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2492
|
+
});
|
|
2493
|
+
for (const locator of record.locators) {
|
|
2494
|
+
try {
|
|
2495
|
+
for (const loc of record.locators) {
|
|
2496
|
+
if (!loc.value)
|
|
2497
|
+
continue;
|
|
2498
|
+
for (const relation of relations) {
|
|
2499
|
+
if (loc.value.includes(relation)) {
|
|
2500
|
+
const relativeXpath = checkReferenceElementIsValid(loc.value, relation, docmt);
|
|
2501
|
+
if (relativeXpath) {
|
|
2502
|
+
createLocator(loc, {
|
|
2503
|
+
name: "xpath",
|
|
2504
|
+
value: relativeXpath,
|
|
2505
|
+
isRecorded: locator.isRecorded !== "" &&
|
|
2506
|
+
locator.isRecorded !== null
|
|
2507
|
+
? locator.isRecorded
|
|
2508
|
+
: "Y",
|
|
2509
|
+
});
|
|
2510
|
+
break;
|
|
2510
2511
|
}
|
|
2511
2512
|
}
|
|
2512
2513
|
}
|
|
2513
2514
|
}
|
|
2514
|
-
catch (error) {
|
|
2515
|
-
console.error("Error processing locator:", locator, error);
|
|
2516
|
-
}
|
|
2517
2515
|
}
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
}));
|
|
2522
|
-
const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
|
|
2523
|
-
if (locator.value &&
|
|
2524
|
-
!unique.some((l) => l.value === locator.value)) {
|
|
2525
|
-
unique.push(locator);
|
|
2526
|
-
}
|
|
2527
|
-
return unique;
|
|
2528
|
-
}, []);
|
|
2529
|
-
const jsonResult = [
|
|
2530
|
-
{
|
|
2531
|
-
name: `${record.name}`,
|
|
2532
|
-
desc: `${record.desc}`,
|
|
2533
|
-
type: `${record.type}`,
|
|
2534
|
-
locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
|
|
2535
|
-
isShared: `${record.isShared}`,
|
|
2536
|
-
projectId: `${record.projectId}`,
|
|
2537
|
-
projectType: `${record.projectType}`,
|
|
2538
|
-
isRecorded: `${record.isRecorded}`,
|
|
2539
|
-
folder: `${record.folder}`,
|
|
2540
|
-
parentId: `${record.parentId}`,
|
|
2541
|
-
parentName: `${record.parentName}`,
|
|
2542
|
-
platform: `${record.platform}`,
|
|
2543
|
-
licenseId: `${record.licenseId}`,
|
|
2544
|
-
licenseType: `${record.licenseType}`,
|
|
2545
|
-
userId: `${record.userId}`,
|
|
2546
|
-
},
|
|
2547
|
-
];
|
|
2548
|
-
return jsonResult;
|
|
2516
|
+
catch (error) {
|
|
2517
|
+
console.error("Error processing locator:", locator, error);
|
|
2518
|
+
}
|
|
2549
2519
|
}
|
|
2520
|
+
const finalAutoHealedLocators = finalLocators.map((obj) => ({
|
|
2521
|
+
...obj,
|
|
2522
|
+
value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
|
|
2523
|
+
}));
|
|
2524
|
+
const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
|
|
2525
|
+
if (locator.value &&
|
|
2526
|
+
!unique.some((l) => l.value === locator.value)) {
|
|
2527
|
+
unique.push(locator);
|
|
2528
|
+
}
|
|
2529
|
+
return unique;
|
|
2530
|
+
}, []);
|
|
2531
|
+
const jsonResult = [
|
|
2532
|
+
{
|
|
2533
|
+
name: `${record.name}`,
|
|
2534
|
+
desc: `${record.desc}`,
|
|
2535
|
+
type: `${record.type}`,
|
|
2536
|
+
locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
|
|
2537
|
+
isShared: `${record.isShared}`,
|
|
2538
|
+
projectId: `${record.projectId}`,
|
|
2539
|
+
projectType: `${record.projectType}`,
|
|
2540
|
+
isRecorded: `${record.isRecorded}`,
|
|
2541
|
+
folder: `${record.folder}`,
|
|
2542
|
+
parentId: `${record.parentId}`,
|
|
2543
|
+
parentName: `${record.parentName}`,
|
|
2544
|
+
platform: `${record.platform}`,
|
|
2545
|
+
licenseId: `${record.licenseId}`,
|
|
2546
|
+
licenseType: `${record.licenseType}`,
|
|
2547
|
+
userId: `${record.userId}`,
|
|
2548
|
+
},
|
|
2549
|
+
];
|
|
2550
|
+
return jsonResult;
|
|
2550
2551
|
}
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2552
|
+
}
|
|
2553
|
+
catch (error) {
|
|
2554
|
+
console.error("Error processing locator:", locator, error);
|
|
2555
|
+
continue;
|
|
2555
2556
|
}
|
|
2556
2557
|
}
|
|
2557
2558
|
catch (error) {
|