-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathselector-finder.js
125 lines (106 loc) · 3.57 KB
/
selector-finder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import finder from '@medv/finder';
const findByCssOrXPath = (doc, sel) => {
let els;
try {
els = doc.querySelectorAll(sel);
} catch (err) {
// eslint-disable-next-line
// console.warn(err);
}
if (!els || els.length === 0) {
try {
let res = doc.evaluate(sel, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
els = [res.singleNodeValue];
} catch (err) {
// eslint-disable-next-line
// console.warn(err);
}
}
return els;
};
export const highlightInIframe = (doc, win, sel) => {
let els = findByCssOrXPath(doc, sel);
if (!els || els.length === 0) {
try {
let res = doc.evaluate(`//*[contains(text(),'${sel}')]`, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
els = [res.singleNodeValue];
} catch (err) {
// eslint-disable-next-line
// console.warn(err);
}
}
if (els) {
els.forEach(el => {
highlightElement(el, doc, win);
});
}
};
export const findShortSelector = (doc, el) => {
try {
return finder(el, {
root: doc,
className: (name) => !name.startsWith('ng-') && !name.startsWith('css-'),
tagName: (name) => !['div', 'span'].includes(name) && !name.startsWith('ng-'),
attr: (name) => ['title', 'name', 'data-test', 'placeholder'].includes(name),
seedMinLength: 1,
optimizedMinLength: 2,
threshold: 1000
});
} catch(_) {
return '';
}
};
export const dehighlightAll = doc => {
try {
const oldOutlines = doc.querySelectorAll('.codeceptjs-outline');
oldOutlines.forEach(ol => ol.remove());
} catch (err) {
// eslint-disable-next-line
// console.warn(err);
}
};
export const highlightElement = (el, doc, win) => {
if (!el) return;
if (!doc) return;
if (!win) return;
const rect = el.getBoundingClientRect();
const shortestSelector = findShortSelector(doc, el);
const highlightColor = 'hsl(348, 100%, 61%)';
var newOutline = doc.createElement('div');
newOutline.className = 'codeceptjs-outline';
newOutline.style.position = 'absolute';
newOutline.style['z-index'] = '9999999999';
newOutline.style['color'] = 'white';
// newOutline.style['border-radius'] = '2px';
// newOutline.style.border = `2px solid ${highlightColor}`
// newOutline.style['padding'] = '1px';
newOutline.style['pointer-events'] = 'none'; // be able to click through this element
newOutline.style.opacity = 0.2;
newOutline.style['background-color'] = highlightColor;
newOutline.style.width = rect.width + 'px';
newOutline.style.height = rect.height + 'px';
newOutline.style.top = rect.top + win.pageYOffset + 'px';
newOutline.style.left = rect.left + win.pageXOffset + 'px';
const textContainer = doc.createElement('div');
textContainer.className = 'codeceptjs-outline';
textContainer.append(doc.createTextNode(shortestSelector));
textContainer.style.position = 'absolute';
textContainer.style['z-index'] = '9999999999';
textContainer.style['pointer-events'] = 'none'; // be able to click through this element
textContainer.style['font-size'] = '.8em';
textContainer.style['background-color'] = highlightColor;
textContainer.style.color = 'white';
textContainer.style.padding = '2px';
textContainer.style.top = rect.top + win.pageYOffset + 'px';
textContainer.style.left = rect.left + win.pageXOffset + 'px';
const docBody = doc.querySelector('body');
docBody.appendChild(newOutline);
docBody.appendChild(textContainer);
return shortestSelector;
};
// export default {
// highlightElement,
// dehighlightAll,
// highlightInIframe,
// findShortSelector,
// }