ff-dom 1.0.18-beta.6 → 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 +198 -196
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +198 -196
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cdn.js +198 -196
- 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.cdn.js
CHANGED
|
@@ -868,9 +868,9 @@
|
|
|
868
868
|
}
|
|
869
869
|
return xpaths1;
|
|
870
870
|
};
|
|
871
|
-
const parseXml = (xmlStr) => {
|
|
871
|
+
const parseXml = (xmlStr, type) => {
|
|
872
872
|
if (window.DOMParser) {
|
|
873
|
-
return new window.DOMParser().parseFromString(xmlStr,
|
|
873
|
+
return new window.DOMParser().parseFromString(xmlStr, type);
|
|
874
874
|
}
|
|
875
875
|
return null;
|
|
876
876
|
};
|
|
@@ -1617,6 +1617,7 @@
|
|
|
1617
1617
|
catch (error) {
|
|
1618
1618
|
console.log(error);
|
|
1619
1619
|
}
|
|
1620
|
+
return xpathData$1;
|
|
1620
1621
|
};
|
|
1621
1622
|
const parseDOM = (element, doc, isIndex, isTarget) => {
|
|
1622
1623
|
xpathData$1 = [];
|
|
@@ -2188,10 +2189,27 @@
|
|
|
2188
2189
|
getReferenceElementXpath,
|
|
2189
2190
|
};
|
|
2190
2191
|
|
|
2191
|
-
const getElementFromShadowRoot = (
|
|
2192
|
-
const shadowRoot = element.shadowRoot;
|
|
2193
|
-
if (shadowRoot && !selector.includes("dynamic")) {
|
|
2194
|
-
|
|
2192
|
+
const getElementFromShadowRoot = (el, selector) => {
|
|
2193
|
+
// const shadowRoot = (element as HTMLElement).shadowRoot;
|
|
2194
|
+
// if (shadowRoot && !selector.includes("dynamic")) {
|
|
2195
|
+
// return shadowRoot.querySelector(selector);
|
|
2196
|
+
// }
|
|
2197
|
+
const elements = Array.from(el.querySelectorAll('*'));
|
|
2198
|
+
try {
|
|
2199
|
+
for (let i = 0; i < elements.length; i++) {
|
|
2200
|
+
if (elements[i].shadowRoot) {
|
|
2201
|
+
const { shadowRoot } = elements[i];
|
|
2202
|
+
if (shadowRoot) {
|
|
2203
|
+
getElementFromShadowRoot(shadowRoot, selector);
|
|
2204
|
+
if (shadowRoot && !selector.includes("dynamic")) {
|
|
2205
|
+
return shadowRoot.querySelector(selector);
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
catch (error) {
|
|
2212
|
+
console.log(error);
|
|
2195
2213
|
}
|
|
2196
2214
|
return null;
|
|
2197
2215
|
};
|
|
@@ -2225,30 +2243,27 @@
|
|
|
2225
2243
|
"/preceding",
|
|
2226
2244
|
"/following",
|
|
2227
2245
|
];
|
|
2228
|
-
function getElementFromXPath(
|
|
2229
|
-
|
|
2230
|
-
const window = currentElement.ownerDocument.defaultView;
|
|
2246
|
+
function getElementFromXPath(docmt, xpath) {
|
|
2247
|
+
const window = docmt.defaultView;
|
|
2231
2248
|
if (!window)
|
|
2232
2249
|
return null;
|
|
2233
2250
|
const xpathEvaluator = new window.XPathEvaluator();
|
|
2234
|
-
const xpathResult = xpathEvaluator.evaluate(xpath,
|
|
2235
|
-
null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2251
|
+
const xpathResult = xpathEvaluator.evaluate(xpath, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2236
2252
|
return xpathResult.singleNodeValue;
|
|
2237
2253
|
}
|
|
2238
|
-
function checkReferenceElementIsValid(locator, relation,
|
|
2254
|
+
function checkReferenceElementIsValid(locator, relation, docmt) {
|
|
2239
2255
|
if (locator.includes(relation)) {
|
|
2240
2256
|
const locatotSplitArray = locator.split(relation);
|
|
2241
2257
|
const sourceLoc = locatotSplitArray[0].trim();
|
|
2242
|
-
|
|
2243
|
-
const window = currentElement.ownerDocument.defaultView;
|
|
2258
|
+
const window = docmt.defaultView;
|
|
2244
2259
|
if (!window)
|
|
2245
2260
|
return null;
|
|
2246
2261
|
if (!locator.includes("dynamic")) {
|
|
2247
2262
|
const xpathEvaluator = new window.XPathEvaluator();
|
|
2248
|
-
const xpathResult = xpathEvaluator.evaluate(sourceLoc,
|
|
2263
|
+
const xpathResult = xpathEvaluator.evaluate(sourceLoc, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2249
2264
|
const sourceElement = xpathResult.singleNodeValue;
|
|
2250
2265
|
if (sourceElement) {
|
|
2251
|
-
const xpathResultComplete = xpathEvaluator.evaluate(locator,
|
|
2266
|
+
const xpathResultComplete = xpathEvaluator.evaluate(locator, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
2252
2267
|
const completeElement = xpathResultComplete.singleNodeValue;
|
|
2253
2268
|
let relativeXpath;
|
|
2254
2269
|
if (completeElement) {
|
|
@@ -2269,16 +2284,12 @@
|
|
|
2269
2284
|
return null;
|
|
2270
2285
|
}
|
|
2271
2286
|
const getElementsFromHTML = (record, docmt) => {
|
|
2272
|
-
const
|
|
2273
|
-
// global.SVGElement = document.defaultView?.SVGElement!;
|
|
2274
|
-
const tempDiv = document.createElement("div");
|
|
2275
|
-
const elementsToRemove = document.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
|
|
2287
|
+
const elementsToRemove = docmt.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
|
|
2276
2288
|
if (elementsToRemove) {
|
|
2277
2289
|
elementsToRemove.forEach((tag) => {
|
|
2278
2290
|
tag.remove();
|
|
2279
2291
|
});
|
|
2280
2292
|
}
|
|
2281
|
-
tempDiv.innerHTML = document.body?.innerHTML;
|
|
2282
2293
|
const finalLocatorsSet = new Set();
|
|
2283
2294
|
let finalLocators = [];
|
|
2284
2295
|
function createLocator(base, overrides = {}) {
|
|
@@ -2352,135 +2363,126 @@
|
|
|
2352
2363
|
if (record.isShared.includes("Y")) {
|
|
2353
2364
|
break locators;
|
|
2354
2365
|
}
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
targetElement = iframeDocument.querySelector(locator.value.slice(6));
|
|
2364
|
-
}
|
|
2366
|
+
try {
|
|
2367
|
+
let targetElement = null;
|
|
2368
|
+
if (locator.value.startsWith("iframe")) {
|
|
2369
|
+
const iframe = docmt.querySelector(locator.value);
|
|
2370
|
+
if (iframe) {
|
|
2371
|
+
const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
|
|
2372
|
+
if (iframeDocument) {
|
|
2373
|
+
targetElement = iframeDocument.querySelector(locator.value.slice(6));
|
|
2365
2374
|
}
|
|
2366
2375
|
}
|
|
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
|
-
}
|
|
2395
|
-
}
|
|
2396
|
-
}
|
|
2397
|
-
else {
|
|
2398
|
-
targetElement = currentElement.querySelector(trimmedSelector);
|
|
2399
|
-
if (!targetElement) {
|
|
2400
|
-
targetElement = getElementFromShadowRoot(currentElement, trimmedSelector);
|
|
2401
|
-
}
|
|
2402
|
-
}
|
|
2403
|
-
if (!targetElement &&
|
|
2404
|
-
isSvg(currentElement) &&
|
|
2405
|
-
!locator.type.match("dynamic")) {
|
|
2406
|
-
targetElement = currentElement.querySelector(trimmedSelector);
|
|
2376
|
+
}
|
|
2377
|
+
else {
|
|
2378
|
+
const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
|
|
2379
|
+
for (const selector of selectors) {
|
|
2380
|
+
if (docmt) {
|
|
2381
|
+
const trimmedSelector = selector.trim();
|
|
2382
|
+
if (locator.name.includes("id") ||
|
|
2383
|
+
trimmedSelector.startsWith("#")) {
|
|
2384
|
+
targetElement = docmt.querySelector("#" + trimmedSelector);
|
|
2385
|
+
}
|
|
2386
|
+
else if (locator.name.includes("className") ||
|
|
2387
|
+
trimmedSelector.startsWith(".")) {
|
|
2388
|
+
targetElement = docmt.querySelector("." + trimmedSelector);
|
|
2389
|
+
}
|
|
2390
|
+
else if ((locator.name.includes("xpath") ||
|
|
2391
|
+
trimmedSelector.startsWith("//")) &&
|
|
2392
|
+
!locator.type.match("dynamic")) {
|
|
2393
|
+
const normalizedXPath = normalizeXPath(trimmedSelector);
|
|
2394
|
+
targetElement = getElementFromXPath(docmt, normalizedXPath);
|
|
2395
|
+
if (targetElement) {
|
|
2396
|
+
createLocator(locator, {
|
|
2397
|
+
value: trimmedSelector,
|
|
2398
|
+
isRecorded: String(locator.isRecorded).includes("N")
|
|
2399
|
+
? "N"
|
|
2400
|
+
: "Y",
|
|
2401
|
+
});
|
|
2407
2402
|
}
|
|
2408
|
-
currentElement = targetElement;
|
|
2409
2403
|
}
|
|
2410
2404
|
else {
|
|
2411
|
-
|
|
2412
|
-
|
|
2405
|
+
targetElement = docmt.querySelector(trimmedSelector);
|
|
2406
|
+
if (!targetElement) {
|
|
2407
|
+
targetElement = getElementFromShadowRoot(docmt.body, trimmedSelector);
|
|
2408
|
+
}
|
|
2413
2409
|
}
|
|
2414
2410
|
}
|
|
2411
|
+
else {
|
|
2412
|
+
console.error("Element not found at:", selector);
|
|
2413
|
+
break;
|
|
2414
|
+
}
|
|
2415
2415
|
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2416
|
+
}
|
|
2417
|
+
const locatorExists = (name, value) => {
|
|
2418
|
+
const key = `${name}:${value}`;
|
|
2419
|
+
return finalLocatorsSet.has(key);
|
|
2420
|
+
};
|
|
2421
|
+
if (targetElement) {
|
|
2422
|
+
const idValue = getId(targetElement);
|
|
2423
|
+
if (idValue && !locatorExists("id", idValue)) {
|
|
2424
|
+
record.locators.forEach((loc) => {
|
|
2425
|
+
createLocator(loc, {
|
|
2426
|
+
name: "id",
|
|
2427
|
+
value: idValue,
|
|
2428
|
+
isRecorded: loc.value === idValue && loc.name === "id"
|
|
2429
|
+
? loc.isRecorded
|
|
2430
|
+
: "Y",
|
|
2431
|
+
isSelfHealed: loc.value === idValue && loc.name === "id"
|
|
2432
|
+
? loc.isSelfHealed
|
|
2433
|
+
: "Y",
|
|
2434
2434
|
});
|
|
2435
|
-
}
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2435
|
+
});
|
|
2436
|
+
}
|
|
2437
|
+
const textValue = getVisibleText(targetElement);
|
|
2438
|
+
if (textValue) {
|
|
2439
|
+
record.locators.forEach((loc) => {
|
|
2440
|
+
createLocator(loc, {
|
|
2441
|
+
name: "linkText",
|
|
2442
|
+
type: "static",
|
|
2443
|
+
value: textValue,
|
|
2444
|
+
isRecorded: loc.value === textValue ? loc.isRecorded : "Y",
|
|
2445
|
+
isSelfHealed: loc.value === textValue ? loc.isSelfHealed : "Y",
|
|
2446
2446
|
});
|
|
2447
|
-
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
const nameLocator = getName(targetElement);
|
|
2450
|
+
if (nameLocator && !locatorExists("name", nameLocator)) {
|
|
2451
|
+
record.locators.forEach((loc) => {
|
|
2452
|
+
createLocator(loc, {
|
|
2453
|
+
name: "name",
|
|
2454
|
+
type: "static",
|
|
2455
|
+
value: nameLocator,
|
|
2456
|
+
isRecorded: loc.value === nameLocator && loc.name === "name"
|
|
2457
|
+
? loc.isRecorded
|
|
2458
|
+
: "Y",
|
|
2459
|
+
isSelfHealed: loc.value === nameLocator && loc.name === "name"
|
|
2460
|
+
? loc.isSelfHealed
|
|
2461
|
+
: "Y",
|
|
2462
2462
|
});
|
|
2463
|
-
}
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2463
|
+
});
|
|
2464
|
+
}
|
|
2465
|
+
const classValue = getClassName(targetElement);
|
|
2466
|
+
if (classValue &&
|
|
2467
|
+
classValue.trim() !== "" &&
|
|
2468
|
+
!locatorExists("className", classValue)) {
|
|
2469
|
+
record.locators.forEach((loc) => {
|
|
2470
|
+
createLocator(loc, {
|
|
2471
|
+
name: "className",
|
|
2472
|
+
value: classValue,
|
|
2473
|
+
isRecorded: loc.value === classValue && loc.name === "className"
|
|
2474
|
+
? loc.isRecorded
|
|
2475
|
+
: "Y",
|
|
2476
|
+
isSelfHealed: loc.value === classValue && loc.name === "className"
|
|
2477
|
+
? loc.isSelfHealed
|
|
2478
|
+
: "Y",
|
|
2479
2479
|
});
|
|
2480
|
-
}
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2482
|
+
const xpathResults = parseDOM(targetElement, docmt, false, true);
|
|
2483
|
+
xpathResults.forEach((result) => {
|
|
2484
|
+
const fnValue = result.value;
|
|
2485
|
+
if (fnValue && !locatorExists(result.key.replace('xpath by', '').trim(), fnValue)) {
|
|
2484
2486
|
record.locators.forEach((loc) => {
|
|
2485
2487
|
createLocator(loc, {
|
|
2486
2488
|
name: 'xpath',
|
|
@@ -2489,71 +2491,71 @@
|
|
|
2489
2491
|
isSelfHealed: loc.value === fnValue ? loc.isSelfHealed : 'Y',
|
|
2490
2492
|
});
|
|
2491
2493
|
});
|
|
2492
|
-
}
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2494
|
+
}
|
|
2495
|
+
});
|
|
2496
|
+
for (const locator of record.locators) {
|
|
2497
|
+
try {
|
|
2498
|
+
for (const loc of record.locators) {
|
|
2499
|
+
if (!loc.value)
|
|
2500
|
+
continue;
|
|
2501
|
+
for (const relation of relations) {
|
|
2502
|
+
if (loc.value.includes(relation)) {
|
|
2503
|
+
const relativeXpath = checkReferenceElementIsValid(loc.value, relation, docmt);
|
|
2504
|
+
if (relativeXpath) {
|
|
2505
|
+
createLocator(loc, {
|
|
2506
|
+
name: "xpath",
|
|
2507
|
+
value: relativeXpath,
|
|
2508
|
+
isRecorded: locator.isRecorded !== "" &&
|
|
2509
|
+
locator.isRecorded !== null
|
|
2510
|
+
? locator.isRecorded
|
|
2511
|
+
: "Y",
|
|
2512
|
+
});
|
|
2513
|
+
break;
|
|
2512
2514
|
}
|
|
2513
2515
|
}
|
|
2514
2516
|
}
|
|
2515
2517
|
}
|
|
2516
|
-
catch (error) {
|
|
2517
|
-
console.error("Error processing locator:", locator, error);
|
|
2518
|
-
}
|
|
2519
2518
|
}
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
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;
|
|
2519
|
+
catch (error) {
|
|
2520
|
+
console.error("Error processing locator:", locator, error);
|
|
2521
|
+
}
|
|
2551
2522
|
}
|
|
2523
|
+
const finalAutoHealedLocators = finalLocators.map((obj) => ({
|
|
2524
|
+
...obj,
|
|
2525
|
+
value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
|
|
2526
|
+
}));
|
|
2527
|
+
const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
|
|
2528
|
+
if (locator.value &&
|
|
2529
|
+
!unique.some((l) => l.value === locator.value)) {
|
|
2530
|
+
unique.push(locator);
|
|
2531
|
+
}
|
|
2532
|
+
return unique;
|
|
2533
|
+
}, []);
|
|
2534
|
+
const jsonResult = [
|
|
2535
|
+
{
|
|
2536
|
+
name: `${record.name}`,
|
|
2537
|
+
desc: `${record.desc}`,
|
|
2538
|
+
type: `${record.type}`,
|
|
2539
|
+
locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
|
|
2540
|
+
isShared: `${record.isShared}`,
|
|
2541
|
+
projectId: `${record.projectId}`,
|
|
2542
|
+
projectType: `${record.projectType}`,
|
|
2543
|
+
isRecorded: `${record.isRecorded}`,
|
|
2544
|
+
folder: `${record.folder}`,
|
|
2545
|
+
parentId: `${record.parentId}`,
|
|
2546
|
+
parentName: `${record.parentName}`,
|
|
2547
|
+
platform: `${record.platform}`,
|
|
2548
|
+
licenseId: `${record.licenseId}`,
|
|
2549
|
+
licenseType: `${record.licenseType}`,
|
|
2550
|
+
userId: `${record.userId}`,
|
|
2551
|
+
},
|
|
2552
|
+
];
|
|
2553
|
+
return jsonResult;
|
|
2552
2554
|
}
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2555
|
+
}
|
|
2556
|
+
catch (error) {
|
|
2557
|
+
console.error("Error processing locator:", locator, error);
|
|
2558
|
+
continue;
|
|
2557
2559
|
}
|
|
2558
2560
|
}
|
|
2559
2561
|
catch (error) {
|
|
@@ -7,7 +7,10 @@ export declare const createXPathAPI: () => {
|
|
|
7
7
|
getTextXPath: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
|
|
8
8
|
getUniqueClassName: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
|
|
9
9
|
attributesBasedXPath: (attr: Attr, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
|
|
10
|
-
addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) =>
|
|
10
|
+
addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => {
|
|
11
|
+
key: string;
|
|
12
|
+
value: string;
|
|
13
|
+
}[];
|
|
11
14
|
addRelativeXpaths: (targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean, attribute: Attr[]) => {
|
|
12
15
|
key: string;
|
|
13
16
|
value: string;
|
|
@@ -45,7 +48,7 @@ export declare const createXPathAPI: () => {
|
|
|
45
48
|
}[];
|
|
46
49
|
};
|
|
47
50
|
xpathUtils: {
|
|
48
|
-
parseXml: (xmlStr: string) => Document | null;
|
|
51
|
+
parseXml: (xmlStr: string, type: DOMParserSupportedType) => Document | null;
|
|
49
52
|
getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
|
|
50
53
|
key: string;
|
|
51
54
|
value: string;
|
|
@@ -14,7 +14,10 @@ declare const xpath: {
|
|
|
14
14
|
getTextXPath: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
|
|
15
15
|
getUniqueClassName: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
|
|
16
16
|
attributesBasedXPath: (attr: Attr, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
|
|
17
|
-
addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) =>
|
|
17
|
+
addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => {
|
|
18
|
+
key: string;
|
|
19
|
+
value: string;
|
|
20
|
+
}[];
|
|
18
21
|
addRelativeXpaths: (targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean, attribute: Attr[]) => {
|
|
19
22
|
key: string;
|
|
20
23
|
value: string;
|
|
@@ -45,11 +45,11 @@ export declare const getReferenceElementsXpath: (domNode: HTMLElement | Element,
|
|
|
45
45
|
key: string;
|
|
46
46
|
value: string;
|
|
47
47
|
}[];
|
|
48
|
-
export declare const parseXml: (xmlStr: string) => Document | null;
|
|
48
|
+
export declare const parseXml: (xmlStr: string, type: DOMParserSupportedType) => Document | null;
|
|
49
49
|
export declare const normalizeXPath: (xpath: string) => string;
|
|
50
50
|
export declare const findMatchingParenthesis: (text: string, openPos: number) => number;
|
|
51
51
|
export declare const xpathUtils: {
|
|
52
|
-
parseXml: (xmlStr: string) => Document | null;
|
|
52
|
+
parseXml: (xmlStr: string, type: DOMParserSupportedType) => Document | null;
|
|
53
53
|
getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
|
|
54
54
|
key: string;
|
|
55
55
|
value: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ElementRecord } from "../types/locator";
|
|
2
2
|
declare function createXPathAPI(): Promise<{
|
|
3
3
|
fromHTML: (html: string) => Promise<{
|
|
4
|
-
autoHeal: (data: ElementRecord, htmlString: string) => Promise<
|
|
4
|
+
autoHeal: (data: ElementRecord, htmlString: string) => Promise<any>;
|
|
5
5
|
}>;
|
|
6
6
|
browser: any;
|
|
7
7
|
}>;
|
package/dist/xpath.mjs
CHANGED
|
@@ -9,10 +9,10 @@ const injectScriptPath = join(_dirname, "index.cdn.js");
|
|
|
9
9
|
const injectScript = readFileSync(injectScriptPath, "utf-8");
|
|
10
10
|
async function createXPathAPI() {
|
|
11
11
|
puppeteer = await import('puppeteer');
|
|
12
|
-
let browser = await puppeteer.launch({ headless: true });
|
|
12
|
+
let browser = await puppeteer.launch({ headless: true, debugger: true });
|
|
13
13
|
let page = await browser.newPage();
|
|
14
14
|
const fromHTML = async (html) => {
|
|
15
|
-
await page?.setContent(html);
|
|
15
|
+
await page?.setContent(html.replace(/\\n/g, '').replaceAll(/\\t/g, '').replace(/\\"/g, '"'), { waitUntil: 'domcontentloaded' });
|
|
16
16
|
await page?.addScriptTag({ content: injectScript });
|
|
17
17
|
page?.on("console", async (msg) => {
|
|
18
18
|
const type = msg.type();
|
|
@@ -45,12 +45,13 @@ async function createXPathAPI() {
|
|
|
45
45
|
});
|
|
46
46
|
return {
|
|
47
47
|
autoHeal: async (data, htmlString) => {
|
|
48
|
-
await page?.evaluate((datum
|
|
48
|
+
return await page?.evaluate((datum) => {
|
|
49
49
|
// @ts-ignore
|
|
50
50
|
let xpathAPI = window.XpathLib.createXPathAPI();
|
|
51
|
-
let
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
let xpaths = xpathAPI.getElementsFromHTML(datum, document);
|
|
52
|
+
// console.log(xpaths);
|
|
53
|
+
return xpaths;
|
|
54
|
+
}, data);
|
|
54
55
|
},
|
|
55
56
|
};
|
|
56
57
|
};
|
package/dist/xpath.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xpath.mjs","sources":["../src/node/xpath.ts"],"sourcesContent":["import { fileURLToPath } from \"url\";\r\nimport path, { join } from \"path\";\r\nimport { readFileSync } from \"fs\";\r\nimport { ElementRecord } from \"../types/locator\";\r\n\r\nconst _filename = fileURLToPath(import.meta.url);\r\nconst _dirname = path.dirname(_filename);\r\n\r\nlet puppeteer: any;\r\n\r\nconst injectScriptPath = join(_dirname, \"index.cdn.js\");\r\nconst injectScript = readFileSync(injectScriptPath, \"utf-8\");\r\n\r\nasync function createXPathAPI() {\r\n puppeteer = await import('puppeteer');\r\n\r\n let browser = await puppeteer.launch({ headless: true });\r\n let page = await browser.newPage();\r\n\r\n const fromHTML = async (html: string) => {\r\n await page?.setContent(html);\r\n await page?.addScriptTag({ content: injectScript });\r\n\r\n page?.on(\r\n \"console\",\r\n async (msg: { type: () => any; text: () => any; args: () => any }) => {\r\n const type = msg.type();\r\n const txt = msg.text();\r\n\r\n const args = msg.args();\r\n if (!args || args.length === 0) {\r\n console.log(`[Browser:${type}]`, txt);\r\n return;\r\n }\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n try {\r\n const arg = args[i];\r\n const obj = arg.remoteObject();\r\n\r\n console.log(obj);\r\n\r\n if (obj.value !== undefined) {\r\n console.log(`[Browser:${type}]`, obj.value);\r\n } else {\r\n const value = await arg.jsonValue().catch(() => txt);\r\n console.log(`[Browser:${type}]`, value);\r\n }\r\n } catch (err) {\r\n console.log(`[Browser:${type}]`, txt);\r\n }\r\n }\r\n }\r\n );\r\n\r\n page?.on(\"pageerror\", (msg: any) => {\r\n console.log(\"error\", msg);\r\n });\r\n\r\n return {\r\n autoHeal: async (data: ElementRecord, htmlString: string) => {\r\n await page?.evaluate((datum: ElementRecord
|
|
1
|
+
{"version":3,"file":"xpath.mjs","sources":["../src/node/xpath.ts"],"sourcesContent":["import { fileURLToPath } from \"url\";\r\nimport path, { join } from \"path\";\r\nimport { readFileSync } from \"fs\";\r\nimport { ElementRecord } from \"../types/locator\";\r\n\r\nconst _filename = fileURLToPath(import.meta.url);\r\nconst _dirname = path.dirname(_filename);\r\n\r\nlet puppeteer: any;\r\n\r\nconst injectScriptPath = join(_dirname, \"index.cdn.js\");\r\nconst injectScript = readFileSync(injectScriptPath, \"utf-8\");\r\n\r\nasync function createXPathAPI() {\r\n puppeteer = await import('puppeteer');\r\n\r\n let browser = await puppeteer.launch({ headless: true, debugger: true });\r\n let page = await browser.newPage();\r\n\r\n const fromHTML = async (html: string) => {\r\n await page?.setContent(html.replace(/\\\\n/g, '').replaceAll(/\\\\t/g, '').replace(/\\\\\"/g, '\"'), { waitUntil: 'domcontentloaded' });\r\n await page?.addScriptTag({ content: injectScript });\r\n\r\n page?.on(\r\n \"console\",\r\n async (msg: { type: () => any; text: () => any; args: () => any }) => {\r\n const type = msg.type();\r\n const txt = msg.text();\r\n\r\n const args = msg.args();\r\n if (!args || args.length === 0) {\r\n console.log(`[Browser:${type}]`, txt);\r\n return;\r\n }\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n try {\r\n const arg = args[i];\r\n const obj = arg.remoteObject();\r\n\r\n console.log(obj);\r\n\r\n if (obj.value !== undefined) {\r\n console.log(`[Browser:${type}]`, obj.value);\r\n } else {\r\n const value = await arg.jsonValue().catch(() => txt);\r\n console.log(`[Browser:${type}]`, value);\r\n }\r\n } catch (err) {\r\n console.log(`[Browser:${type}]`, txt);\r\n }\r\n }\r\n }\r\n );\r\n\r\n page?.on(\"pageerror\", (msg: any) => {\r\n console.log(\"error\", msg);\r\n });\r\n\r\n return {\r\n autoHeal: async (data: ElementRecord, htmlString: string) => {\r\n return await page?.evaluate((datum: ElementRecord) => {\r\n // @ts-ignore\r\n let xpathAPI = window.XpathLib.createXPathAPI();\r\n let xpaths = xpathAPI.getElementsFromHTML(datum, document);\r\n // console.log(xpaths);\r\n return xpaths;\r\n }, data);\r\n },\r\n };\r\n };\r\n\r\n return { fromHTML, browser };\r\n}\r\n\r\nexport default createXPathAPI;\r\n"],"names":[],"mappings":"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"}
|