ff-dom 1.0.2 → 1.0.4
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.
|
@@ -7,7 +7,7 @@ const isUnique = (xpathResult) => {
|
|
|
7
7
|
};
|
|
8
8
|
const getElementFromShadowRoot = (element, selector) => {
|
|
9
9
|
const shadowRoot = element.shadowRoot;
|
|
10
|
-
if (shadowRoot) {
|
|
10
|
+
if (shadowRoot && !selector.includes("dynamic")) {
|
|
11
11
|
return shadowRoot.querySelector(selector);
|
|
12
12
|
}
|
|
13
13
|
return null;
|
|
@@ -66,6 +66,16 @@ const getXpathByName = (element) => {
|
|
|
66
66
|
}
|
|
67
67
|
return null;
|
|
68
68
|
};
|
|
69
|
+
const getName = (element) => {
|
|
70
|
+
const elementEl = element;
|
|
71
|
+
if (elementEl.hasAttribute("name")) {
|
|
72
|
+
const attrValue = elementEl.getAttribute("name");
|
|
73
|
+
const name = `${attrValue}`;
|
|
74
|
+
console.log("get name", name);
|
|
75
|
+
return name || null;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
};
|
|
69
79
|
const getXpathByPlaceholder = (element) => {
|
|
70
80
|
const selector = element.nodeName.toLowerCase();
|
|
71
81
|
const elementEl = element;
|
|
@@ -135,26 +145,28 @@ function checkReferenceElementIsValid(locator, relation, tempDiv) {
|
|
|
135
145
|
const window = currentElement.ownerDocument.defaultView;
|
|
136
146
|
if (!window)
|
|
137
147
|
return null;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
if (!locator.includes("dynamic")) {
|
|
149
|
+
const xpathEvaluator = new window.XPathEvaluator();
|
|
150
|
+
const xpathResult = xpathEvaluator.evaluate(sourceLoc, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
151
|
+
const sourceElement = xpathResult.singleNodeValue;
|
|
152
|
+
if (sourceElement) {
|
|
153
|
+
const xpathResultComplete = xpathEvaluator.evaluate(locator, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
154
|
+
const completeElement = xpathResultComplete.singleNodeValue;
|
|
155
|
+
let relativeXpath;
|
|
156
|
+
if (completeElement) {
|
|
157
|
+
relativeXpath = locator;
|
|
158
|
+
return relativeXpath;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.error("Complete Locator is Invalid:", locator);
|
|
162
|
+
relativeXpath = locator;
|
|
163
|
+
return relativeXpath;
|
|
164
|
+
}
|
|
148
165
|
}
|
|
149
166
|
else {
|
|
150
|
-
console.error("
|
|
151
|
-
relativeXpath = locator;
|
|
152
|
-
return relativeXpath;
|
|
167
|
+
console.error("Source Locator Not Found:", sourceLoc);
|
|
153
168
|
}
|
|
154
169
|
}
|
|
155
|
-
else {
|
|
156
|
-
console.error("Source Locator Not Found:", sourceLoc);
|
|
157
|
-
}
|
|
158
170
|
}
|
|
159
171
|
return null;
|
|
160
172
|
}
|
|
@@ -165,9 +177,40 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
165
177
|
const tempDiv = document.createElement("div");
|
|
166
178
|
tempDiv.innerHTML = htmlString;
|
|
167
179
|
let finalLocators = [];
|
|
168
|
-
for (const locator of locators) {
|
|
180
|
+
locators: for (const locator of locators) {
|
|
169
181
|
try {
|
|
170
182
|
let relativeXpath = null;
|
|
183
|
+
if (locator.value.includes("dynamic") ||
|
|
184
|
+
locator.type.match("dynamic") ||
|
|
185
|
+
locator.value.includes("{") ||
|
|
186
|
+
locator.value.includes("}")) {
|
|
187
|
+
console.log("Dynamic locator detected:", locator.value);
|
|
188
|
+
finalLocators.push({
|
|
189
|
+
name: locator.name,
|
|
190
|
+
type: locator.type,
|
|
191
|
+
value: locator.value,
|
|
192
|
+
reference: locator.reference,
|
|
193
|
+
status: locator.status,
|
|
194
|
+
isRecorded: locator.isRecorded,
|
|
195
|
+
});
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (locator.isRecorded.includes("N") || locator.isRecorded.match("N")) {
|
|
199
|
+
console.log("Manually added locator detected:", locator.value);
|
|
200
|
+
finalLocators.push({
|
|
201
|
+
name: locator.name,
|
|
202
|
+
type: locator.type,
|
|
203
|
+
value: locator.value,
|
|
204
|
+
reference: locator.reference,
|
|
205
|
+
status: locator.status,
|
|
206
|
+
isRecorded: locator.isRecorded,
|
|
207
|
+
});
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (isShared.includes("Y")) {
|
|
211
|
+
console.log("Shared element detected");
|
|
212
|
+
break locators;
|
|
213
|
+
}
|
|
171
214
|
for (const relation of relations) {
|
|
172
215
|
try {
|
|
173
216
|
let targetElement = null;
|
|
@@ -194,8 +237,9 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
194
237
|
trimmedSelector.startsWith(".")) {
|
|
195
238
|
targetElement = currentElement.querySelector("." + trimmedSelector);
|
|
196
239
|
}
|
|
197
|
-
else if (locator.name.includes("xpath") ||
|
|
198
|
-
trimmedSelector.startsWith("//"))
|
|
240
|
+
else if ((locator.name.includes("xpath") ||
|
|
241
|
+
trimmedSelector.startsWith("//")) &&
|
|
242
|
+
!locator.type.match("dynamic")) {
|
|
199
243
|
targetElement = getElementFromXPath(tempDiv, trimmedSelector);
|
|
200
244
|
}
|
|
201
245
|
else {
|
|
@@ -204,7 +248,9 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
204
248
|
targetElement = getElementFromShadowRoot(currentElement, trimmedSelector);
|
|
205
249
|
}
|
|
206
250
|
}
|
|
207
|
-
if (!targetElement &&
|
|
251
|
+
if (!targetElement &&
|
|
252
|
+
isSVGElement(currentElement) &&
|
|
253
|
+
!locator.type.match("dynamic")) {
|
|
208
254
|
targetElement = currentElement.querySelector(trimmedSelector);
|
|
209
255
|
}
|
|
210
256
|
currentElement = targetElement;
|
|
@@ -212,7 +258,10 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
212
258
|
}
|
|
213
259
|
}
|
|
214
260
|
const locatorExists = (name, value) => {
|
|
215
|
-
return finalLocators.some((loc) => loc.name === name &&
|
|
261
|
+
return finalLocators.some((loc) => loc.name === name &&
|
|
262
|
+
loc.value === value &&
|
|
263
|
+
(!loc.value.includes("dynamic") ||
|
|
264
|
+
!locator.type.match("dynamic")));
|
|
216
265
|
};
|
|
217
266
|
const xpathFunctions = [
|
|
218
267
|
{ name: "xpath", value: getXPathByText },
|
|
@@ -222,7 +271,6 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
222
271
|
{ name: "xpath", value: getXpathByName },
|
|
223
272
|
{ name: "xpath", value: getXpathByPlaceholder },
|
|
224
273
|
{ name: "xpath", value: getXpathByType },
|
|
225
|
-
{ name: "xpath", value: getVisibleText },
|
|
226
274
|
];
|
|
227
275
|
if (targetElement) {
|
|
228
276
|
const idValue = getId(targetElement);
|
|
@@ -236,6 +284,29 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
236
284
|
isRecorded: locator.isRecorded,
|
|
237
285
|
});
|
|
238
286
|
}
|
|
287
|
+
if (getVisibleText(targetElement)) {
|
|
288
|
+
const textValue = getVisibleText(targetElement);
|
|
289
|
+
finalLocators.push({
|
|
290
|
+
name: "linkText",
|
|
291
|
+
type: "static",
|
|
292
|
+
value: textValue,
|
|
293
|
+
reference: locator.reference,
|
|
294
|
+
status: locator.status,
|
|
295
|
+
isRecorded: locator.isRecorded,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
if (getName(targetElement)) {
|
|
299
|
+
console.log("inside name if");
|
|
300
|
+
const nameLocator = getName(targetElement);
|
|
301
|
+
finalLocators.push({
|
|
302
|
+
name: "name",
|
|
303
|
+
type: "static",
|
|
304
|
+
value: nameLocator,
|
|
305
|
+
reference: locator.reference,
|
|
306
|
+
status: locator.status,
|
|
307
|
+
isRecorded: locator.isRecorded,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
239
310
|
const classValue = getClassName(targetElement);
|
|
240
311
|
if (classValue &&
|
|
241
312
|
classValue.trim() !== "" &&
|
package/package.json
CHANGED
|
@@ -24,7 +24,7 @@ const getElementFromShadowRoot = (
|
|
|
24
24
|
selector: string
|
|
25
25
|
): Element | null => {
|
|
26
26
|
const shadowRoot = (element as HTMLElement).shadowRoot;
|
|
27
|
-
if (shadowRoot) {
|
|
27
|
+
if (shadowRoot && !selector.includes("dynamic")) {
|
|
28
28
|
return shadowRoot.querySelector(selector);
|
|
29
29
|
}
|
|
30
30
|
return null;
|
|
@@ -103,6 +103,19 @@ const getXpathByName = (element: Element): string | null => {
|
|
|
103
103
|
return null;
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
+
const getName = (element: Element): string | null => {
|
|
107
|
+
const elementEl = element as HTMLElement;
|
|
108
|
+
|
|
109
|
+
if (elementEl.hasAttribute("name")) {
|
|
110
|
+
const attrValue = elementEl.getAttribute("name");
|
|
111
|
+
const name = `${attrValue}`;
|
|
112
|
+
console.log("get name", name);
|
|
113
|
+
return name || null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return null;
|
|
117
|
+
};
|
|
118
|
+
|
|
106
119
|
const getXpathByPlaceholder = (element: Element): string | null => {
|
|
107
120
|
const selector = element.nodeName.toLowerCase();
|
|
108
121
|
const elementEl = element as HTMLElement;
|
|
@@ -195,37 +208,38 @@ function checkReferenceElementIsValid(
|
|
|
195
208
|
let currentElement: Element | null = tempDiv;
|
|
196
209
|
const window = currentElement.ownerDocument.defaultView;
|
|
197
210
|
if (!window) return null;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
currentElement.ownerDocument,
|
|
203
|
-
null,
|
|
204
|
-
window.XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
205
|
-
null
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
const sourceElement = xpathResult.singleNodeValue;
|
|
209
|
-
if (sourceElement) {
|
|
210
|
-
const xpathResultComplete = xpathEvaluator.evaluate(
|
|
211
|
-
locator,
|
|
211
|
+
if (!locator.includes("dynamic")) {
|
|
212
|
+
const xpathEvaluator = new window.XPathEvaluator();
|
|
213
|
+
const xpathResult = xpathEvaluator.evaluate(
|
|
214
|
+
sourceLoc,
|
|
212
215
|
currentElement.ownerDocument,
|
|
213
216
|
null,
|
|
214
217
|
window.XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
215
218
|
null
|
|
216
219
|
);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
|
|
221
|
+
const sourceElement = xpathResult.singleNodeValue;
|
|
222
|
+
if (sourceElement) {
|
|
223
|
+
const xpathResultComplete = xpathEvaluator.evaluate(
|
|
224
|
+
locator,
|
|
225
|
+
currentElement.ownerDocument,
|
|
226
|
+
null,
|
|
227
|
+
window.XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
228
|
+
null
|
|
229
|
+
);
|
|
230
|
+
const completeElement = xpathResultComplete.singleNodeValue;
|
|
231
|
+
let relativeXpath: string;
|
|
232
|
+
if (completeElement) {
|
|
233
|
+
relativeXpath = locator;
|
|
234
|
+
return relativeXpath;
|
|
235
|
+
} else {
|
|
236
|
+
console.error("Complete Locator is Invalid:", locator);
|
|
237
|
+
relativeXpath = locator;
|
|
238
|
+
return relativeXpath;
|
|
239
|
+
}
|
|
222
240
|
} else {
|
|
223
|
-
console.error("
|
|
224
|
-
relativeXpath = locator;
|
|
225
|
-
return relativeXpath;
|
|
241
|
+
console.error("Source Locator Not Found:", sourceLoc);
|
|
226
242
|
}
|
|
227
|
-
} else {
|
|
228
|
-
console.error("Source Locator Not Found:", sourceLoc);
|
|
229
243
|
}
|
|
230
244
|
}
|
|
231
245
|
return null;
|
|
@@ -262,9 +276,42 @@ const getElementsFromHTML = (
|
|
|
262
276
|
tempDiv.innerHTML = htmlString;
|
|
263
277
|
let finalLocators = [];
|
|
264
278
|
|
|
265
|
-
for (const locator of locators) {
|
|
279
|
+
locators: for (const locator of locators) {
|
|
266
280
|
try {
|
|
267
281
|
let relativeXpath: string | null = null;
|
|
282
|
+
if (
|
|
283
|
+
locator.value.includes("dynamic") ||
|
|
284
|
+
locator.type.match("dynamic") ||
|
|
285
|
+
locator.value.includes("{") ||
|
|
286
|
+
locator.value.includes("}")
|
|
287
|
+
) {
|
|
288
|
+
console.log("Dynamic locator detected:", locator.value);
|
|
289
|
+
finalLocators.push({
|
|
290
|
+
name: locator.name,
|
|
291
|
+
type: locator.type,
|
|
292
|
+
value: locator.value,
|
|
293
|
+
reference: locator.reference,
|
|
294
|
+
status: locator.status,
|
|
295
|
+
isRecorded: locator.isRecorded,
|
|
296
|
+
});
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (locator.isRecorded.includes("N") || locator.isRecorded.match("N")) {
|
|
300
|
+
console.log("Manually added locator detected:", locator.value);
|
|
301
|
+
finalLocators.push({
|
|
302
|
+
name: locator.name,
|
|
303
|
+
type: locator.type,
|
|
304
|
+
value: locator.value,
|
|
305
|
+
reference: locator.reference,
|
|
306
|
+
status: locator.status,
|
|
307
|
+
isRecorded: locator.isRecorded,
|
|
308
|
+
});
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (isShared.includes("Y")) {
|
|
312
|
+
console.log("Shared element detected");
|
|
313
|
+
break locators;
|
|
314
|
+
}
|
|
268
315
|
for (const relation of relations) {
|
|
269
316
|
try {
|
|
270
317
|
let targetElement: Element | null = null;
|
|
@@ -303,8 +350,9 @@ const getElementsFromHTML = (
|
|
|
303
350
|
"." + trimmedSelector
|
|
304
351
|
);
|
|
305
352
|
} else if (
|
|
306
|
-
locator.name.includes("xpath") ||
|
|
307
|
-
|
|
353
|
+
(locator.name.includes("xpath") ||
|
|
354
|
+
trimmedSelector.startsWith("//")) &&
|
|
355
|
+
!locator.type.match("dynamic")
|
|
308
356
|
) {
|
|
309
357
|
targetElement = getElementFromXPath(tempDiv, trimmedSelector);
|
|
310
358
|
} else {
|
|
@@ -317,7 +365,11 @@ const getElementsFromHTML = (
|
|
|
317
365
|
}
|
|
318
366
|
}
|
|
319
367
|
|
|
320
|
-
if (
|
|
368
|
+
if (
|
|
369
|
+
!targetElement &&
|
|
370
|
+
isSVGElement(currentElement) &&
|
|
371
|
+
!locator.type.match("dynamic")
|
|
372
|
+
) {
|
|
321
373
|
targetElement = currentElement.querySelector(trimmedSelector);
|
|
322
374
|
}
|
|
323
375
|
|
|
@@ -328,7 +380,11 @@ const getElementsFromHTML = (
|
|
|
328
380
|
|
|
329
381
|
const locatorExists = (name: string, value: string) => {
|
|
330
382
|
return finalLocators.some(
|
|
331
|
-
(loc) =>
|
|
383
|
+
(loc) =>
|
|
384
|
+
loc.name === name &&
|
|
385
|
+
loc.value === value &&
|
|
386
|
+
(!loc.value.includes("dynamic") ||
|
|
387
|
+
!locator.type.match("dynamic"))
|
|
332
388
|
);
|
|
333
389
|
};
|
|
334
390
|
|
|
@@ -340,7 +396,6 @@ const getElementsFromHTML = (
|
|
|
340
396
|
{ name: "xpath", value: getXpathByName },
|
|
341
397
|
{ name: "xpath", value: getXpathByPlaceholder },
|
|
342
398
|
{ name: "xpath", value: getXpathByType },
|
|
343
|
-
{ name: "xpath", value: getVisibleText },
|
|
344
399
|
];
|
|
345
400
|
|
|
346
401
|
if (targetElement) {
|
|
@@ -355,6 +410,30 @@ const getElementsFromHTML = (
|
|
|
355
410
|
isRecorded: locator.isRecorded,
|
|
356
411
|
});
|
|
357
412
|
}
|
|
413
|
+
if (getVisibleText(targetElement)) {
|
|
414
|
+
const textValue = getVisibleText(targetElement);
|
|
415
|
+
finalLocators.push({
|
|
416
|
+
name: "linkText",
|
|
417
|
+
type: "static",
|
|
418
|
+
value: textValue,
|
|
419
|
+
reference: locator.reference,
|
|
420
|
+
status: locator.status,
|
|
421
|
+
isRecorded: locator.isRecorded,
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (getName(targetElement)) {
|
|
426
|
+
console.log("inside name if");
|
|
427
|
+
const nameLocator = getName(targetElement);
|
|
428
|
+
finalLocators.push({
|
|
429
|
+
name: "name",
|
|
430
|
+
type: "static",
|
|
431
|
+
value: nameLocator,
|
|
432
|
+
reference: locator.reference,
|
|
433
|
+
status: locator.status,
|
|
434
|
+
isRecorded: locator.isRecorded,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
358
437
|
|
|
359
438
|
const classValue = getClassName(targetElement);
|
|
360
439
|
if (
|