crawlee-one 1.0.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/README.md +81 -0
- package/dist/cjs/cli/cli.d.ts +1 -0
- package/dist/cjs/cli/cli.js +61 -0
- package/dist/cjs/cli/cli.js.map +1 -0
- package/dist/cjs/cli/index.d.ts +2 -0
- package/dist/cjs/cli/index.js +6 -0
- package/dist/cjs/cli/index.js.map +1 -0
- package/dist/cjs/index.d.ts +24 -0
- package/dist/cjs/index.js +43 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lib/actions/dom.d.ts +102 -0
- package/dist/cjs/lib/actions/dom.js +743 -0
- package/dist/cjs/lib/actions/dom.js.map +1 -0
- package/dist/cjs/lib/actions/domUtils.d.ts +42 -0
- package/dist/cjs/lib/actions/domUtils.js +126 -0
- package/dist/cjs/lib/actions/domUtils.js.map +1 -0
- package/dist/cjs/lib/actions/page.d.ts +69 -0
- package/dist/cjs/lib/actions/page.js +205 -0
- package/dist/cjs/lib/actions/page.js.map +1 -0
- package/dist/cjs/lib/actions/scrapeListing.d.ts +78 -0
- package/dist/cjs/lib/actions/scrapeListing.js +242 -0
- package/dist/cjs/lib/actions/scrapeListing.js.map +1 -0
- package/dist/cjs/lib/actor/actor.d.ts +90 -0
- package/dist/cjs/lib/actor/actor.js +306 -0
- package/dist/cjs/lib/actor/actor.js.map +1 -0
- package/dist/cjs/lib/actor/types.d.ts +162 -0
- package/dist/cjs/lib/actor/types.js +3 -0
- package/dist/cjs/lib/actor/types.js.map +1 -0
- package/dist/cjs/lib/actor.d.ts +189 -0
- package/dist/cjs/lib/actor.js +225 -0
- package/dist/cjs/lib/actor.js.map +1 -0
- package/dist/cjs/lib/actorSpec.d.ts +20 -0
- package/dist/cjs/lib/actorSpec.js +3 -0
- package/dist/cjs/lib/actorSpec.js.map +1 -0
- package/dist/cjs/lib/config.d.ts +561 -0
- package/dist/cjs/lib/config.js +707 -0
- package/dist/cjs/lib/config.js.map +1 -0
- package/dist/cjs/lib/dataset/maxCount.d.ts +30 -0
- package/dist/cjs/lib/dataset/maxCount.js +55 -0
- package/dist/cjs/lib/dataset/maxCount.js.map +1 -0
- package/dist/cjs/lib/dataset/pushData.d.ts +123 -0
- package/dist/cjs/lib/dataset/pushData.js +182 -0
- package/dist/cjs/lib/dataset/pushData.js.map +1 -0
- package/dist/cjs/lib/dataset.d.ts +98 -0
- package/dist/cjs/lib/dataset.js +122 -0
- package/dist/cjs/lib/dataset.js.map +1 -0
- package/dist/cjs/lib/dom.d.ts +78 -0
- package/dist/cjs/lib/dom.js +243 -0
- package/dist/cjs/lib/dom.js.map +1 -0
- package/dist/cjs/lib/error/errorHandler.d.ts +112 -0
- package/dist/cjs/lib/error/errorHandler.js +164 -0
- package/dist/cjs/lib/error/errorHandler.js.map +1 -0
- package/dist/cjs/lib/error/sentry.d.ts +11 -0
- package/dist/cjs/lib/error/sentry.js +60 -0
- package/dist/cjs/lib/error/sentry.js.map +1 -0
- package/dist/cjs/lib/integrations/apify.d.ts +67 -0
- package/dist/cjs/lib/integrations/apify.js +106 -0
- package/dist/cjs/lib/integrations/apify.js.map +1 -0
- package/dist/cjs/lib/integrations/types.d.ts +274 -0
- package/dist/cjs/lib/integrations/types.js +3 -0
- package/dist/cjs/lib/integrations/types.js.map +1 -0
- package/dist/cjs/lib/io/dataset.d.ts +67 -0
- package/dist/cjs/lib/io/dataset.js +86 -0
- package/dist/cjs/lib/io/dataset.js.map +1 -0
- package/dist/cjs/lib/io/maxCount.d.ts +30 -0
- package/dist/cjs/lib/io/maxCount.js +55 -0
- package/dist/cjs/lib/io/maxCount.js.map +1 -0
- package/dist/cjs/lib/io/pushData.d.ts +124 -0
- package/dist/cjs/lib/io/pushData.js +193 -0
- package/dist/cjs/lib/io/pushData.js.map +1 -0
- package/dist/cjs/lib/io/pushRequests.d.ts +38 -0
- package/dist/cjs/lib/io/pushRequests.js +63 -0
- package/dist/cjs/lib/io/pushRequests.js.map +1 -0
- package/dist/cjs/lib/io/requestQueue.d.ts +28 -0
- package/dist/cjs/lib/io/requestQueue.js +40 -0
- package/dist/cjs/lib/io/requestQueue.js.map +1 -0
- package/dist/cjs/lib/log.d.ts +38 -0
- package/dist/cjs/lib/log.js +54 -0
- package/dist/cjs/lib/log.js.map +1 -0
- package/dist/cjs/lib/migrate/localMigrator.d.ts +10 -0
- package/dist/cjs/lib/migrate/localMigrator.js +57 -0
- package/dist/cjs/lib/migrate/localMigrator.js.map +1 -0
- package/dist/cjs/lib/migrate/localState.d.ts +7 -0
- package/dist/cjs/lib/migrate/localState.js +43 -0
- package/dist/cjs/lib/migrate/localState.js.map +1 -0
- package/dist/cjs/lib/migrate/types.d.ts +6 -0
- package/dist/cjs/lib/migrate/types.js +3 -0
- package/dist/cjs/lib/migrate/types.js.map +1 -0
- package/dist/cjs/lib/readme/readme.d.ts +65 -0
- package/dist/cjs/lib/readme/readme.js +534 -0
- package/dist/cjs/lib/readme/readme.js.map +1 -0
- package/dist/cjs/lib/readme/types.d.ts +260 -0
- package/dist/cjs/lib/readme/types.js +54 -0
- package/dist/cjs/lib/readme/types.js.map +1 -0
- package/dist/cjs/lib/router.d.ts +132 -0
- package/dist/cjs/lib/router.js +165 -0
- package/dist/cjs/lib/router.js.map +1 -0
- package/dist/cjs/lib/scraper/scrapeListing.d.ts +78 -0
- package/dist/cjs/lib/scraper/scrapeListing.js +242 -0
- package/dist/cjs/lib/scraper/scrapeListing.js.map +1 -0
- package/dist/cjs/lib/test/actor.d.ts +21 -0
- package/dist/cjs/lib/test/actor.js +56 -0
- package/dist/cjs/lib/test/actor.js.map +1 -0
- package/dist/cjs/lib/test/mockApifyClient.d.ts +32 -0
- package/dist/cjs/lib/test/mockApifyClient.js +176 -0
- package/dist/cjs/lib/test/mockApifyClient.js.map +1 -0
- package/dist/cjs/types.d.ts +31 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils/async.d.ts +19 -0
- package/dist/cjs/utils/async.js +74 -0
- package/dist/cjs/utils/async.js.map +1 -0
- package/dist/cjs/utils/error.d.ts +1 -0
- package/dist/cjs/utils/error.js +10 -0
- package/dist/cjs/utils/error.js.map +1 -0
- package/dist/cjs/utils/format.d.ts +9 -0
- package/dist/cjs/utils/format.js +19 -0
- package/dist/cjs/utils/format.js.map +1 -0
- package/dist/cjs/utils/package.d.ts +15 -0
- package/dist/cjs/utils/package.js +25 -0
- package/dist/cjs/utils/package.js.map +1 -0
- package/dist/cjs/utils/types.d.ts +6 -0
- package/dist/cjs/utils/types.js +9 -0
- package/dist/cjs/utils/types.js.map +1 -0
- package/dist/cjs/utils/url.d.ts +9 -0
- package/dist/cjs/utils/url.js +32 -0
- package/dist/cjs/utils/url.js.map +1 -0
- package/dist/cjs/utils/valueMonitor.d.ts +31 -0
- package/dist/cjs/utils/valueMonitor.js +91 -0
- package/dist/cjs/utils/valueMonitor.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,743 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.playwrightLocatorDOMLib = exports.playwrightHandleDOMLib = exports.cheerioDOMLib = exports.browserDOMLib = void 0;
|
|
16
|
+
const get_1 = __importDefault(require("lodash/get"));
|
|
17
|
+
const format_1 = require("../../utils/format");
|
|
18
|
+
const url_1 = require("../../utils/url");
|
|
19
|
+
const domUtils_1 = require("./domUtils");
|
|
20
|
+
const error_1 = require("../../utils/error");
|
|
21
|
+
/** Implementation of DOMLib in browser (using Browser API) */
|
|
22
|
+
const browserDOMLib = (node) => {
|
|
23
|
+
///////////////////////
|
|
24
|
+
// SCALAR OPERATIONS
|
|
25
|
+
///////////////////////
|
|
26
|
+
const text = ({ allowEmpty } = {}) => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
const txt = (_b = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : null;
|
|
29
|
+
return (0, format_1.strOrNull)(txt, allowEmpty);
|
|
30
|
+
};
|
|
31
|
+
const textAsUpper = (options) => {
|
|
32
|
+
const txt = text(options);
|
|
33
|
+
return txt ? txt.toLocaleUpperCase() : txt;
|
|
34
|
+
};
|
|
35
|
+
const textAsLower = (options) => {
|
|
36
|
+
const txt = text(options);
|
|
37
|
+
return txt ? txt.toLocaleLowerCase() : txt;
|
|
38
|
+
};
|
|
39
|
+
const textAsNumber = (options) => {
|
|
40
|
+
const txt = text(options);
|
|
41
|
+
return (0, format_1.strAsNumber)(txt, options);
|
|
42
|
+
};
|
|
43
|
+
const prop = (propOrPath, { allowEmpty = false } = {}) => {
|
|
44
|
+
var _a;
|
|
45
|
+
const propPath = Array.isArray(propOrPath) ? propOrPath : [propOrPath];
|
|
46
|
+
let propVal = (_a = (0, get_1.default)(node, propPath)) !== null && _a !== void 0 ? _a : null;
|
|
47
|
+
propVal = typeof propVal === 'string' ? propVal.trim() : propVal;
|
|
48
|
+
return (0, format_1.strOrNull)(propVal, allowEmpty);
|
|
49
|
+
};
|
|
50
|
+
const props = (propsOrPaths, options = {}) => {
|
|
51
|
+
const propPaths = propsOrPaths.map((p) => (Array.isArray(p) ? p : [p]));
|
|
52
|
+
const propData = propPaths.map((path) => prop(path, options));
|
|
53
|
+
return propData;
|
|
54
|
+
};
|
|
55
|
+
const attr = (propName, { allowEmpty } = {}) => {
|
|
56
|
+
var _a;
|
|
57
|
+
let attrVal = (_a = node.getAttribute(propName)) !== null && _a !== void 0 ? _a : null;
|
|
58
|
+
attrVal = typeof attrVal === 'string' ? attrVal.trim() : attrVal;
|
|
59
|
+
return (0, format_1.strOrNull)(attrVal, allowEmpty);
|
|
60
|
+
};
|
|
61
|
+
const attrs = (attrNames, options = {}) => {
|
|
62
|
+
const attrData = attrNames.reduce((agg, name) => {
|
|
63
|
+
agg[name] = attr(name, options);
|
|
64
|
+
return agg;
|
|
65
|
+
}, {});
|
|
66
|
+
return attrData;
|
|
67
|
+
};
|
|
68
|
+
const href = ({ allowEmpty, allowRelative, baseUrl } = {}) => {
|
|
69
|
+
const val = prop('href', { allowEmpty });
|
|
70
|
+
return (0, url_1.formatUrl)(val, { allowRelative, baseUrl });
|
|
71
|
+
};
|
|
72
|
+
const src = ({ allowEmpty, allowRelative, baseUrl } = {}) => {
|
|
73
|
+
const val = prop('src', { allowEmpty });
|
|
74
|
+
return (0, url_1.formatUrl)(val, { allowRelative, baseUrl });
|
|
75
|
+
};
|
|
76
|
+
const nodeName = () => {
|
|
77
|
+
// On UPPER- vs lower-case https://stackoverflow.com/questions/27223756/
|
|
78
|
+
const val = prop('nodeName');
|
|
79
|
+
return typeof val === 'string' ? val.toLocaleUpperCase() : val;
|
|
80
|
+
};
|
|
81
|
+
const url = () => {
|
|
82
|
+
var _a, _b;
|
|
83
|
+
const doc = node.ownerDocument;
|
|
84
|
+
// See https://stackoverflow.com/a/16010322/9788634
|
|
85
|
+
const urlVal = ((_b = (_a = doc.defaultView) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.href) || null;
|
|
86
|
+
return urlVal;
|
|
87
|
+
};
|
|
88
|
+
const map = (mapFn) => {
|
|
89
|
+
return mapFn(node);
|
|
90
|
+
};
|
|
91
|
+
///////////////////////
|
|
92
|
+
// NODE OPERATIONS
|
|
93
|
+
///////////////////////
|
|
94
|
+
const findOne = (selector) => {
|
|
95
|
+
var _a;
|
|
96
|
+
if (![Node.ELEMENT_NODE, Node.DOCUMENT_NODE].includes(node.nodeType))
|
|
97
|
+
return null;
|
|
98
|
+
const resultEl = ((_a = node.querySelector(selector)) !== null && _a !== void 0 ? _a : null);
|
|
99
|
+
return resultEl ? (0, exports.browserDOMLib)(resultEl) : null;
|
|
100
|
+
};
|
|
101
|
+
const findMany = (selector) => {
|
|
102
|
+
if (![Node.ELEMENT_NODE, Node.DOCUMENT_NODE].includes(node.nodeType))
|
|
103
|
+
return [];
|
|
104
|
+
const resultEls = [...node.querySelectorAll(selector)]; // prettier-ignore
|
|
105
|
+
return resultEls.map((el) => (0, exports.browserDOMLib)(el));
|
|
106
|
+
};
|
|
107
|
+
const closest = (selector) => {
|
|
108
|
+
var _a;
|
|
109
|
+
if (![Node.ELEMENT_NODE, Node.DOCUMENT_NODE].includes(node.nodeType))
|
|
110
|
+
return null;
|
|
111
|
+
const resultEl = ((_a = node.closest(selector)) !== null && _a !== void 0 ? _a : null);
|
|
112
|
+
return resultEl ? (0, exports.browserDOMLib)(resultEl) : null;
|
|
113
|
+
};
|
|
114
|
+
const parent = () => {
|
|
115
|
+
const parentEl = (node.parentNode || null);
|
|
116
|
+
return parentEl ? (0, exports.browserDOMLib)(parentEl) : null;
|
|
117
|
+
};
|
|
118
|
+
const children = () => {
|
|
119
|
+
const childEls = [...node.children];
|
|
120
|
+
return childEls.map((el) => (0, exports.browserDOMLib)(el));
|
|
121
|
+
};
|
|
122
|
+
const root = () => {
|
|
123
|
+
var _a;
|
|
124
|
+
const rootEl = (((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.documentElement) || null);
|
|
125
|
+
return rootEl ? (0, exports.browserDOMLib)(rootEl) : null;
|
|
126
|
+
};
|
|
127
|
+
const remove = () => {
|
|
128
|
+
node.remove();
|
|
129
|
+
};
|
|
130
|
+
const _getCommonAncestor = (el1, el2) => {
|
|
131
|
+
// https://stackoverflow.com/a/25154092
|
|
132
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Range/commonAncestorContainer
|
|
133
|
+
const _getCommonAncestorFromRange = (el1, el2) => {
|
|
134
|
+
const range = new Range();
|
|
135
|
+
range.setStartBefore(el1);
|
|
136
|
+
range.setEndAfter(el2);
|
|
137
|
+
const containerEl = range.commonAncestorContainer;
|
|
138
|
+
return containerEl;
|
|
139
|
+
};
|
|
140
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
|
|
141
|
+
const isEl1BeforeEl2 = !!(el1.compareDocumentPosition(el2) & Node.DOCUMENT_POSITION_FOLLOWING);
|
|
142
|
+
const { firstEl, lastEl } = isEl1BeforeEl2
|
|
143
|
+
? { firstEl: el1, lastEl: el2 }
|
|
144
|
+
: { firstEl: el2, lastEl: el1 };
|
|
145
|
+
const containerEl = _getCommonAncestorFromRange(firstEl, lastEl);
|
|
146
|
+
return containerEl;
|
|
147
|
+
};
|
|
148
|
+
const getCommonAncestor = (otherEl) => {
|
|
149
|
+
const ancestor = _getCommonAncestor(node, otherEl);
|
|
150
|
+
return ancestor ? (0, exports.browserDOMLib)(ancestor) : null;
|
|
151
|
+
};
|
|
152
|
+
const _getCommonAncestorFromSelector = _createCommonAncestorFromSelectorFn({
|
|
153
|
+
querySelectorAll: (selector) => node.querySelectorAll(selector),
|
|
154
|
+
getParent: (el) => el.parentElement,
|
|
155
|
+
isAncestor: (el1, el2) => {
|
|
156
|
+
return !!(el1.compareDocumentPosition(el2) & Node.DOCUMENT_POSITION_CONTAINED_BY);
|
|
157
|
+
},
|
|
158
|
+
getCommonAncestor: (el1, el2) => _getCommonAncestor(el1, el2),
|
|
159
|
+
});
|
|
160
|
+
const getCommonAncestorFromSelector = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
161
|
+
const ancestor = (yield _getCommonAncestorFromSelector(selector));
|
|
162
|
+
return ancestor ? (0, exports.browserDOMLib)(ancestor) : null;
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
node,
|
|
166
|
+
text,
|
|
167
|
+
textAsLower,
|
|
168
|
+
textAsUpper,
|
|
169
|
+
textAsNumber,
|
|
170
|
+
attr,
|
|
171
|
+
attrs,
|
|
172
|
+
prop,
|
|
173
|
+
props,
|
|
174
|
+
href,
|
|
175
|
+
src,
|
|
176
|
+
nodeName,
|
|
177
|
+
url,
|
|
178
|
+
map,
|
|
179
|
+
findOne,
|
|
180
|
+
findMany,
|
|
181
|
+
closest,
|
|
182
|
+
parent,
|
|
183
|
+
children,
|
|
184
|
+
root,
|
|
185
|
+
remove,
|
|
186
|
+
getCommonAncestor,
|
|
187
|
+
getCommonAncestorFromSelector,
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
exports.browserDOMLib = browserDOMLib;
|
|
191
|
+
/** Implementation of DOMLib in Cheerio */
|
|
192
|
+
const cheerioDOMLib = (cheerioNode, srcUrl) => {
|
|
193
|
+
///////////////////////
|
|
194
|
+
// SCALAR OPERATIONS
|
|
195
|
+
///////////////////////
|
|
196
|
+
const text = ({ allowEmpty } = {}) => {
|
|
197
|
+
var _a, _b;
|
|
198
|
+
const txt = (_b = (_a = cheerioNode.text()) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : null;
|
|
199
|
+
return (0, format_1.strOrNull)(txt, allowEmpty);
|
|
200
|
+
};
|
|
201
|
+
const textAsUpper = (options) => {
|
|
202
|
+
const txt = text(options);
|
|
203
|
+
return txt ? txt.toLocaleUpperCase() : txt;
|
|
204
|
+
};
|
|
205
|
+
const textAsLower = (options) => {
|
|
206
|
+
const txt = text(options);
|
|
207
|
+
return txt ? txt.toLocaleLowerCase() : txt;
|
|
208
|
+
};
|
|
209
|
+
const textAsNumber = (options) => {
|
|
210
|
+
const txt = text(options);
|
|
211
|
+
return (0, format_1.strAsNumber)(txt, options);
|
|
212
|
+
};
|
|
213
|
+
const attr = (attrName, { allowEmpty } = {}) => {
|
|
214
|
+
var _a;
|
|
215
|
+
let attrVal = (_a = cheerioNode.attr(attrName)) !== null && _a !== void 0 ? _a : null;
|
|
216
|
+
attrVal = typeof attrVal === 'string' ? attrVal.trim() : attrVal;
|
|
217
|
+
return (0, format_1.strOrNull)(attrVal, allowEmpty);
|
|
218
|
+
};
|
|
219
|
+
const attrs = (attrNames, options = {}) => {
|
|
220
|
+
const attrData = attrNames.reduce((agg, name) => {
|
|
221
|
+
agg[name] = attr(name, options);
|
|
222
|
+
return agg;
|
|
223
|
+
}, {});
|
|
224
|
+
return attrData;
|
|
225
|
+
};
|
|
226
|
+
const prop = (propOrPath, { allowEmpty = false } = {}) => {
|
|
227
|
+
var _a;
|
|
228
|
+
const propPath = Array.isArray(propOrPath) ? propOrPath : [propOrPath];
|
|
229
|
+
let propVal = (_a = cheerioNode.prop(propPath[0])) !== null && _a !== void 0 ? _a : null;
|
|
230
|
+
if (propPath.length > 1)
|
|
231
|
+
propVal = (0, get_1.default)(propVal, propPath.slice(1));
|
|
232
|
+
propVal = typeof propVal === 'string' ? propVal.trim() : propVal;
|
|
233
|
+
return (0, format_1.strOrNull)(propVal, allowEmpty);
|
|
234
|
+
};
|
|
235
|
+
const props = (propsOrPaths, options = {}) => {
|
|
236
|
+
const propPaths = propsOrPaths.map((p) => (Array.isArray(p) ? p : [p]));
|
|
237
|
+
const propData = propPaths.map((path) => prop(path, options));
|
|
238
|
+
return propData;
|
|
239
|
+
};
|
|
240
|
+
const href = ({ allowEmpty, allowRelative, baseUrl } = {}) => {
|
|
241
|
+
const val = prop('href', { allowEmpty });
|
|
242
|
+
return (0, url_1.formatUrl)(val, { allowRelative, baseUrl });
|
|
243
|
+
};
|
|
244
|
+
const src = ({ allowEmpty, allowRelative, baseUrl } = {}) => {
|
|
245
|
+
const val = prop('src', { allowEmpty });
|
|
246
|
+
return (0, url_1.formatUrl)(val, { allowRelative, baseUrl });
|
|
247
|
+
};
|
|
248
|
+
const nodeName = () => {
|
|
249
|
+
// On UPPER- vs lower-case https://stackoverflow.com/questions/27223756/
|
|
250
|
+
const val = prop('nodeName');
|
|
251
|
+
return typeof val === 'string' ? val.toLocaleUpperCase() : val;
|
|
252
|
+
};
|
|
253
|
+
const url = () => {
|
|
254
|
+
return srcUrl !== null && srcUrl !== void 0 ? srcUrl : null;
|
|
255
|
+
};
|
|
256
|
+
const map = (mapFn) => {
|
|
257
|
+
return mapFn(cheerioNode);
|
|
258
|
+
};
|
|
259
|
+
///////////////////////
|
|
260
|
+
// NODE OPERATIONS
|
|
261
|
+
///////////////////////
|
|
262
|
+
const findOne = (selector) => {
|
|
263
|
+
const resultEl = cheerioNode.find(selector).first();
|
|
264
|
+
if (!resultEl.get(0))
|
|
265
|
+
return null;
|
|
266
|
+
return (0, exports.cheerioDOMLib)(resultEl, srcUrl);
|
|
267
|
+
};
|
|
268
|
+
const findMany = (selector) => {
|
|
269
|
+
const resultEls = (0, domUtils_1.splitCheerioSelection)(cheerioNode.find(selector));
|
|
270
|
+
return resultEls.map((ch) => (0, exports.cheerioDOMLib)(ch, srcUrl));
|
|
271
|
+
};
|
|
272
|
+
const closest = (selector) => {
|
|
273
|
+
const resultEl = cheerioNode.closest(selector).first();
|
|
274
|
+
if (!resultEl.get(0))
|
|
275
|
+
return null;
|
|
276
|
+
return (0, exports.cheerioDOMLib)(resultEl, srcUrl);
|
|
277
|
+
};
|
|
278
|
+
const parent = () => {
|
|
279
|
+
const parentEl = cheerioNode.parent().first();
|
|
280
|
+
if (!parentEl.get(0))
|
|
281
|
+
return null;
|
|
282
|
+
return (0, exports.cheerioDOMLib)(parentEl, srcUrl);
|
|
283
|
+
};
|
|
284
|
+
const children = () => {
|
|
285
|
+
const childEls = (0, domUtils_1.splitCheerioSelection)(cheerioNode.children());
|
|
286
|
+
return childEls.map((ch) => (0, exports.cheerioDOMLib)(ch, srcUrl));
|
|
287
|
+
};
|
|
288
|
+
const root = () => {
|
|
289
|
+
var _a;
|
|
290
|
+
const rootEl = (_a = cheerioNode._root) === null || _a === void 0 ? void 0 : _a.first();
|
|
291
|
+
if (!(rootEl === null || rootEl === void 0 ? void 0 : rootEl.get(0)))
|
|
292
|
+
return null;
|
|
293
|
+
return (0, exports.cheerioDOMLib)(rootEl, srcUrl);
|
|
294
|
+
};
|
|
295
|
+
const remove = () => {
|
|
296
|
+
cheerioNode.remove();
|
|
297
|
+
};
|
|
298
|
+
/** Function that finds the closest common ancestor for `el1` and `el2`. */
|
|
299
|
+
const _getCommonAncestor = (el1, el2) => __awaiter(void 0, void 0, void 0, function* () {
|
|
300
|
+
const ch1Parents = (0, domUtils_1.splitCheerioSelection)(el1.parents());
|
|
301
|
+
const ch2Parents = (0, domUtils_1.splitCheerioSelection)(el2.parents());
|
|
302
|
+
let commonAncestor = null;
|
|
303
|
+
for (const comparerParent of ch1Parents) {
|
|
304
|
+
for (const compareeParent of ch2Parents) {
|
|
305
|
+
if (!comparerParent.is(compareeParent))
|
|
306
|
+
continue;
|
|
307
|
+
commonAncestor = comparerParent;
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
if (commonAncestor)
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
return commonAncestor;
|
|
314
|
+
});
|
|
315
|
+
const getCommonAncestor = (otherEl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
316
|
+
const ancestor = (yield _getCommonAncestor(cheerioNode, otherEl));
|
|
317
|
+
if (!(ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(0)))
|
|
318
|
+
return null;
|
|
319
|
+
return (0, exports.cheerioDOMLib)(ancestor, srcUrl);
|
|
320
|
+
});
|
|
321
|
+
const _getCommonAncestorFromSelector = _createCommonAncestorFromSelectorFn({
|
|
322
|
+
querySelectorAll: (selector) => (0, domUtils_1.splitCheerioSelection)(cheerioNode.find(selector)),
|
|
323
|
+
getParent: (el) => el.parent(),
|
|
324
|
+
isAncestor: (el1, el2) => el1.is(el2.parents()),
|
|
325
|
+
getCommonAncestor: (el1, el2) => _getCommonAncestor(el1, el2),
|
|
326
|
+
});
|
|
327
|
+
const getCommonAncestorFromSelector = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
328
|
+
const ancestor = (yield _getCommonAncestorFromSelector(selector));
|
|
329
|
+
if (!(ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(0)))
|
|
330
|
+
return null;
|
|
331
|
+
return (0, exports.cheerioDOMLib)(ancestor, srcUrl);
|
|
332
|
+
});
|
|
333
|
+
return {
|
|
334
|
+
node: cheerioNode,
|
|
335
|
+
text,
|
|
336
|
+
textAsLower,
|
|
337
|
+
textAsUpper,
|
|
338
|
+
textAsNumber,
|
|
339
|
+
attr,
|
|
340
|
+
attrs,
|
|
341
|
+
prop,
|
|
342
|
+
props,
|
|
343
|
+
href,
|
|
344
|
+
src,
|
|
345
|
+
nodeName,
|
|
346
|
+
url,
|
|
347
|
+
map,
|
|
348
|
+
findOne,
|
|
349
|
+
findMany,
|
|
350
|
+
closest,
|
|
351
|
+
parent,
|
|
352
|
+
children,
|
|
353
|
+
root,
|
|
354
|
+
remove,
|
|
355
|
+
getCommonAncestor,
|
|
356
|
+
getCommonAncestorFromSelector,
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
exports.cheerioDOMLib = cheerioDOMLib;
|
|
360
|
+
const verifyHandleEl = (el) => __awaiter(void 0, void 0, void 0, function* () {
|
|
361
|
+
if (!el)
|
|
362
|
+
return null;
|
|
363
|
+
const exists = yield el.evaluate((el) => !!el).catch(error_1.logAndRethrow);
|
|
364
|
+
return exists ? el : null;
|
|
365
|
+
});
|
|
366
|
+
/** Implementation of DOMLib in Playwright using Handles */
|
|
367
|
+
const playwrightHandleDOMLib = (node, page) => {
|
|
368
|
+
///////////////////////
|
|
369
|
+
// SCALAR OPERATIONS
|
|
370
|
+
///////////////////////
|
|
371
|
+
const text = ({ allowEmpty } = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
372
|
+
var _a, _b;
|
|
373
|
+
const txt = (_b = (_a = (yield node.textContent())) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : null;
|
|
374
|
+
return (0, format_1.strOrNull)(txt, allowEmpty);
|
|
375
|
+
});
|
|
376
|
+
const textAsUpper = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
377
|
+
const txt = yield text(options);
|
|
378
|
+
return txt ? txt.toLocaleUpperCase() : txt;
|
|
379
|
+
});
|
|
380
|
+
const textAsLower = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
381
|
+
const txt = yield text(options);
|
|
382
|
+
return txt ? txt.toLocaleLowerCase() : txt;
|
|
383
|
+
});
|
|
384
|
+
const textAsNumber = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
385
|
+
const txt = yield text(options);
|
|
386
|
+
return (0, format_1.strAsNumber)(txt, options);
|
|
387
|
+
});
|
|
388
|
+
const prop = (propOrPath, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
389
|
+
const [resProp] = yield props([propOrPath], options);
|
|
390
|
+
return resProp;
|
|
391
|
+
});
|
|
392
|
+
const props = (propsOrPaths, { allowEmpty = false } = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
393
|
+
const propPaths = propsOrPaths.map((p) => (Array.isArray(p) ? p : [p]));
|
|
394
|
+
const data = yield node
|
|
395
|
+
.evaluate((el, { propPaths, allowEmpty }) => {
|
|
396
|
+
return propPaths.map((propPath) => {
|
|
397
|
+
let val = el;
|
|
398
|
+
for (const prop of propPath) {
|
|
399
|
+
if (el == null)
|
|
400
|
+
break;
|
|
401
|
+
val = val[prop];
|
|
402
|
+
}
|
|
403
|
+
val = typeof val === 'string' ? val.trim() : val;
|
|
404
|
+
return (0, format_1.strOrNull)(val, allowEmpty);
|
|
405
|
+
});
|
|
406
|
+
}, { propPaths, allowEmpty })
|
|
407
|
+
.catch(error_1.logAndRethrow);
|
|
408
|
+
return data;
|
|
409
|
+
});
|
|
410
|
+
const attr = (attrName, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
411
|
+
var _c;
|
|
412
|
+
const data = yield attrs([attrName], options);
|
|
413
|
+
return (_c = data[attrName]) !== null && _c !== void 0 ? _c : null;
|
|
414
|
+
});
|
|
415
|
+
const attrs = (attrNames, { allowEmpty = false } = {}) => {
|
|
416
|
+
const data = node
|
|
417
|
+
.evaluate((el, { attrNames, allowEmpty }) => {
|
|
418
|
+
const attrData = attrNames.reduce((agg, name) => {
|
|
419
|
+
var _a;
|
|
420
|
+
let attrVal = (_a = el.getAttribute(name)) !== null && _a !== void 0 ? _a : null;
|
|
421
|
+
attrVal = typeof attrVal === 'string' ? attrVal.trim() : attrVal;
|
|
422
|
+
agg[name] = (0, format_1.strOrNull)(attrVal, allowEmpty);
|
|
423
|
+
return agg;
|
|
424
|
+
}, {});
|
|
425
|
+
return attrData;
|
|
426
|
+
}, { attrNames, allowEmpty })
|
|
427
|
+
.catch(error_1.logAndRethrow);
|
|
428
|
+
return data;
|
|
429
|
+
};
|
|
430
|
+
const href = ({ allowEmpty, allowRelative, baseUrl, } = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
431
|
+
const val = (yield prop('href', { allowEmpty }));
|
|
432
|
+
return (0, url_1.formatUrl)(val, { allowRelative, baseUrl });
|
|
433
|
+
});
|
|
434
|
+
const src = ({ allowEmpty, allowRelative, baseUrl, } = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
435
|
+
const val = (yield prop('src', { allowEmpty }));
|
|
436
|
+
return (0, url_1.formatUrl)(val, { allowRelative, baseUrl });
|
|
437
|
+
});
|
|
438
|
+
const nodeName = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
439
|
+
// On UPPER- vs lower-case https://stackoverflow.com/questions/27223756/
|
|
440
|
+
const val = (yield prop('nodeName'));
|
|
441
|
+
return typeof val === 'string' ? val.toLocaleUpperCase() : val;
|
|
442
|
+
});
|
|
443
|
+
const url = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
444
|
+
return page.url() || null;
|
|
445
|
+
});
|
|
446
|
+
const map = (mapFn) => {
|
|
447
|
+
return mapFn(node);
|
|
448
|
+
};
|
|
449
|
+
///////////////////////
|
|
450
|
+
// NODE OPERATIONS
|
|
451
|
+
///////////////////////
|
|
452
|
+
const findOne = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
453
|
+
const resultEl = yield node
|
|
454
|
+
.evaluateHandle((el, s) => {
|
|
455
|
+
if (![Node.ELEMENT_NODE, Node.DOCUMENT_NODE].includes(el.nodeType))
|
|
456
|
+
return null;
|
|
457
|
+
return el.querySelector(s) || null;
|
|
458
|
+
}, selector)
|
|
459
|
+
.catch(error_1.logAndRethrow);
|
|
460
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
461
|
+
return hasResult ? (0, exports.playwrightHandleDOMLib)(resultEl, page) : null;
|
|
462
|
+
});
|
|
463
|
+
const findMany = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
464
|
+
const elsHandle = yield node
|
|
465
|
+
.evaluateHandle((el, s) => {
|
|
466
|
+
if (![Node.ELEMENT_NODE, Node.DOCUMENT_NODE].includes(el.nodeType))
|
|
467
|
+
return [];
|
|
468
|
+
return [...el.querySelectorAll(s)];
|
|
469
|
+
}, selector)
|
|
470
|
+
.catch(error_1.logAndRethrow);
|
|
471
|
+
const resultEls = yield (0, domUtils_1.splitPlaywrightSelection)(elsHandle);
|
|
472
|
+
return resultEls.map((el) => (0, exports.playwrightHandleDOMLib)(el, page));
|
|
473
|
+
});
|
|
474
|
+
const closest = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
475
|
+
const resultEl = yield node
|
|
476
|
+
.evaluateHandle((el, s) => {
|
|
477
|
+
if (![Node.ELEMENT_NODE, Node.DOCUMENT_NODE].includes(el.nodeType))
|
|
478
|
+
return null;
|
|
479
|
+
return el.closest(s) || null;
|
|
480
|
+
}, selector)
|
|
481
|
+
.catch(error_1.logAndRethrow);
|
|
482
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
483
|
+
return hasResult ? (0, exports.playwrightHandleDOMLib)(resultEl, page) : null;
|
|
484
|
+
});
|
|
485
|
+
const parent = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
486
|
+
const resultEl = yield node
|
|
487
|
+
.evaluateHandle((el) => el.parentElement || null)
|
|
488
|
+
.catch(error_1.logAndRethrow);
|
|
489
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
490
|
+
return hasResult ? (0, exports.playwrightHandleDOMLib)(resultEl, page) : null;
|
|
491
|
+
});
|
|
492
|
+
const children = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
493
|
+
const elsHandle = yield node
|
|
494
|
+
.evaluateHandle((el) => [...el.children])
|
|
495
|
+
.catch(error_1.logAndRethrow);
|
|
496
|
+
const resultEls = yield (0, domUtils_1.splitPlaywrightSelection)(elsHandle);
|
|
497
|
+
return resultEls.map((el) => (0, exports.playwrightHandleDOMLib)(el, page));
|
|
498
|
+
});
|
|
499
|
+
const root = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
500
|
+
const resultEl = yield node
|
|
501
|
+
.evaluateHandle((el) => { var _a; return ((_a = el.ownerDocument) === null || _a === void 0 ? void 0 : _a.documentElement) || null; })
|
|
502
|
+
.catch(error_1.logAndRethrow);
|
|
503
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
504
|
+
return hasResult ? (0, exports.playwrightHandleDOMLib)(resultEl, page) : null;
|
|
505
|
+
});
|
|
506
|
+
const remove = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
507
|
+
yield node.evaluate((el) => el.remove()).catch(error_1.logAndRethrow);
|
|
508
|
+
});
|
|
509
|
+
const _getCommonAncestor = (loc1, loc2) => __awaiter(void 0, void 0, void 0, function* () {
|
|
510
|
+
const isEl1BeforeEl2 = yield (yield (0, domUtils_1.mergeHandles)([loc1, loc2]))
|
|
511
|
+
.evaluate(([el1, el2]) => {
|
|
512
|
+
if (!el1 || !el2)
|
|
513
|
+
return false;
|
|
514
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
|
|
515
|
+
const result = !!(el1.compareDocumentPosition(el2) & Node.DOCUMENT_POSITION_FOLLOWING);
|
|
516
|
+
return result;
|
|
517
|
+
})
|
|
518
|
+
.catch(error_1.logAndRethrow);
|
|
519
|
+
const { firstEl, lastEl } = isEl1BeforeEl2
|
|
520
|
+
? { firstEl: loc1, lastEl: loc2 }
|
|
521
|
+
: { firstEl: loc2, lastEl: loc1 };
|
|
522
|
+
const ancestor = yield (yield (0, domUtils_1.mergeHandles)([firstEl, lastEl]))
|
|
523
|
+
.evaluateHandle(([el1, el2]) => {
|
|
524
|
+
if (!el1 || !el2)
|
|
525
|
+
return null;
|
|
526
|
+
// https://stackoverflow.com/a/25154092
|
|
527
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Range/commonAncestorContainer
|
|
528
|
+
const range = new Range();
|
|
529
|
+
range.setStartBefore(el1);
|
|
530
|
+
range.setEndAfter(el2);
|
|
531
|
+
const containerEl = range.commonAncestorContainer;
|
|
532
|
+
return containerEl;
|
|
533
|
+
})
|
|
534
|
+
.catch(error_1.logAndRethrow);
|
|
535
|
+
const hasResult = yield ancestor.evaluate((el) => !!el).catch(error_1.logAndRethrow);
|
|
536
|
+
return hasResult ? ancestor : null;
|
|
537
|
+
});
|
|
538
|
+
const getCommonAncestor = (otherEl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
539
|
+
const resultEl = (yield _getCommonAncestor(node, otherEl));
|
|
540
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
541
|
+
return resultEl && hasResult ? (0, exports.playwrightHandleDOMLib)(resultEl, page) : null;
|
|
542
|
+
});
|
|
543
|
+
const _getCommonAncestorFromSelector = _createCommonAncestorFromSelectorFn({
|
|
544
|
+
querySelectorAll: (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
545
|
+
const resultEls = (yield findMany(selector)).map((d) => d.node).filter(Boolean);
|
|
546
|
+
return resultEls;
|
|
547
|
+
}),
|
|
548
|
+
getParent: (el) => __awaiter(void 0, void 0, void 0, function* () {
|
|
549
|
+
var _d, _e;
|
|
550
|
+
return (_e = (_d = (yield (0, exports.playwrightHandleDOMLib)(el, page).parent())) === null || _d === void 0 ? void 0 : _d.node) !== null && _e !== void 0 ? _e : null;
|
|
551
|
+
}),
|
|
552
|
+
isAncestor: (el1, el2) => __awaiter(void 0, void 0, void 0, function* () {
|
|
553
|
+
return (yield (0, domUtils_1.mergeHandles)([el1, el2]))
|
|
554
|
+
.evaluate(([el1, el2]) => {
|
|
555
|
+
if (!el1 || !el2)
|
|
556
|
+
return false;
|
|
557
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
|
|
558
|
+
const result = !!(el1.compareDocumentPosition(el2) & Node.DOCUMENT_POSITION_CONTAINED_BY);
|
|
559
|
+
return result;
|
|
560
|
+
})
|
|
561
|
+
.catch(error_1.logAndRethrow);
|
|
562
|
+
}),
|
|
563
|
+
getCommonAncestor: _getCommonAncestor,
|
|
564
|
+
});
|
|
565
|
+
const getCommonAncestorFromSelector = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
566
|
+
const resultEl = (yield _getCommonAncestorFromSelector(selector));
|
|
567
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
568
|
+
return resultEl && hasResult ? (0, exports.playwrightHandleDOMLib)(resultEl, page) : null;
|
|
569
|
+
});
|
|
570
|
+
return {
|
|
571
|
+
node,
|
|
572
|
+
text,
|
|
573
|
+
textAsLower,
|
|
574
|
+
textAsUpper,
|
|
575
|
+
textAsNumber,
|
|
576
|
+
attr,
|
|
577
|
+
attrs,
|
|
578
|
+
prop,
|
|
579
|
+
props,
|
|
580
|
+
href,
|
|
581
|
+
src,
|
|
582
|
+
nodeName,
|
|
583
|
+
url,
|
|
584
|
+
map,
|
|
585
|
+
findOne,
|
|
586
|
+
findMany,
|
|
587
|
+
closest,
|
|
588
|
+
parent,
|
|
589
|
+
children,
|
|
590
|
+
root,
|
|
591
|
+
remove,
|
|
592
|
+
getCommonAncestor,
|
|
593
|
+
getCommonAncestorFromSelector,
|
|
594
|
+
};
|
|
595
|
+
};
|
|
596
|
+
exports.playwrightHandleDOMLib = playwrightHandleDOMLib;
|
|
597
|
+
/** Implementation of DOMLib in Playwright using Locators */
|
|
598
|
+
const playwrightLocatorDOMLib = (node, page) => {
|
|
599
|
+
// NOTE: Where possible, make use of the already-existing logic for Handles
|
|
600
|
+
const handleDom = (0, exports.playwrightHandleDOMLib)(node, page);
|
|
601
|
+
///////////////////////
|
|
602
|
+
// SCALAR OPERATIONS
|
|
603
|
+
///////////////////////
|
|
604
|
+
/** Empty */
|
|
605
|
+
///////////////////////
|
|
606
|
+
// NODE OPERATIONS
|
|
607
|
+
///////////////////////
|
|
608
|
+
const findOne = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
609
|
+
const resultEl = node.locator(selector);
|
|
610
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
611
|
+
return hasResult ? (0, exports.playwrightLocatorDOMLib)(resultEl, page) : null;
|
|
612
|
+
});
|
|
613
|
+
const findMany = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
614
|
+
const resultEls = yield node.locator(selector).all();
|
|
615
|
+
return resultEls.map((el) => (0, exports.playwrightLocatorDOMLib)(el, page));
|
|
616
|
+
});
|
|
617
|
+
const closest = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
618
|
+
// Find closest ancestor matching the given selector.
|
|
619
|
+
// See https://stackoverflow.com/a/40333166/9788634
|
|
620
|
+
const resultEl = node.locator(`xpath=ancestor::${selector.trim()}[position() = 1]`);
|
|
621
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
622
|
+
return hasResult ? (0, exports.playwrightLocatorDOMLib)(resultEl, page) : null;
|
|
623
|
+
});
|
|
624
|
+
const parent = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
625
|
+
return closest('*');
|
|
626
|
+
});
|
|
627
|
+
const children = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
628
|
+
const resultEls = yield node.locator('xpath=child::*').all();
|
|
629
|
+
return resultEls.map((el) => (0, exports.playwrightLocatorDOMLib)(el, page));
|
|
630
|
+
});
|
|
631
|
+
const root = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
632
|
+
// Find closest ancestor matching the given selector.
|
|
633
|
+
// See https://stackoverflow.com/a/40333166/9788634 and https://stackoverflow.com/q/31562639/9788634
|
|
634
|
+
const resultEl = node.locator(`xpath=ancestor::*[position() = last()]`);
|
|
635
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
636
|
+
return hasResult ? (0, exports.playwrightLocatorDOMLib)(resultEl, page) : null;
|
|
637
|
+
});
|
|
638
|
+
const remove = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
639
|
+
yield node.evaluate((el) => el.remove()).catch(error_1.logAndRethrow);
|
|
640
|
+
});
|
|
641
|
+
/** Function that finds the closest common ancestor for `el1` and `el2`. */
|
|
642
|
+
const _getCommonAncestor = (el1, el2) => __awaiter(void 0, void 0, void 0, function* () {
|
|
643
|
+
const ch1Parents = yield el1.locator(`xpath=ancestor::*`).all();
|
|
644
|
+
const ch2Parents = yield el2.locator(`xpath=ancestor::*`).all();
|
|
645
|
+
let commonAncestor = null;
|
|
646
|
+
for (const comparerParent of ch1Parents) {
|
|
647
|
+
for (const compareeParent of ch2Parents) {
|
|
648
|
+
const handle = yield (0, domUtils_1.mergeHandles)([comparerParent, compareeParent]);
|
|
649
|
+
const isSame = yield handle.evaluate(([el1, el2]) => {
|
|
650
|
+
return el1 === el2;
|
|
651
|
+
});
|
|
652
|
+
if (isSame) {
|
|
653
|
+
commonAncestor = comparerParent;
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (commonAncestor)
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
return commonAncestor;
|
|
661
|
+
});
|
|
662
|
+
const getCommonAncestor = (otherEl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
663
|
+
const resultEl = (yield _getCommonAncestor(node, otherEl));
|
|
664
|
+
const hasResult = yield verifyHandleEl(resultEl);
|
|
665
|
+
return resultEl && hasResult ? (0, exports.playwrightLocatorDOMLib)(resultEl, page) : null;
|
|
666
|
+
});
|
|
667
|
+
const _getCommonAncestorFromSelector = _createCommonAncestorFromSelectorFn({
|
|
668
|
+
querySelectorAll: (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
669
|
+
const resultEls = (yield findMany(selector)).map((d) => d.node).filter(Boolean);
|
|
670
|
+
return resultEls;
|
|
671
|
+
}),
|
|
672
|
+
getParent: (el) => __awaiter(void 0, void 0, void 0, function* () {
|
|
673
|
+
var _a, _b;
|
|
674
|
+
return (_b = (_a = (yield (0, exports.playwrightLocatorDOMLib)(el, page).parent())) === null || _a === void 0 ? void 0 : _a.node) !== null && _b !== void 0 ? _b : null;
|
|
675
|
+
}),
|
|
676
|
+
isAncestor: (el1, el2) => __awaiter(void 0, void 0, void 0, function* () {
|
|
677
|
+
return (yield (0, domUtils_1.mergeHandles)([el1, el2]))
|
|
678
|
+
.evaluate(([el1, el2]) => {
|
|
679
|
+
if (!el1 || !el2)
|
|
680
|
+
return false;
|
|
681
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
|
|
682
|
+
const result = !!(el1.compareDocumentPosition(el2) & Node.DOCUMENT_POSITION_CONTAINED_BY);
|
|
683
|
+
return result;
|
|
684
|
+
})
|
|
685
|
+
.catch(error_1.logAndRethrow);
|
|
686
|
+
}),
|
|
687
|
+
getCommonAncestor: _getCommonAncestor,
|
|
688
|
+
});
|
|
689
|
+
const getCommonAncestorFromSelector = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
690
|
+
const ancestor = (yield _getCommonAncestorFromSelector(selector));
|
|
691
|
+
const hasResult = yield (ancestor === null || ancestor === void 0 ? void 0 : ancestor.evaluate((el) => !!el).catch(error_1.logAndRethrow));
|
|
692
|
+
return ancestor && hasResult ? (0, exports.playwrightHandleDOMLib)(ancestor, page) : null;
|
|
693
|
+
});
|
|
694
|
+
return {
|
|
695
|
+
node,
|
|
696
|
+
text: handleDom.text,
|
|
697
|
+
textAsLower: handleDom.textAsLower,
|
|
698
|
+
textAsUpper: handleDom.textAsUpper,
|
|
699
|
+
textAsNumber: handleDom.textAsNumber,
|
|
700
|
+
attr: handleDom.attr,
|
|
701
|
+
attrs: handleDom.attrs,
|
|
702
|
+
prop: handleDom.prop,
|
|
703
|
+
props: handleDom.props,
|
|
704
|
+
href: handleDom.href,
|
|
705
|
+
src: handleDom.src,
|
|
706
|
+
nodeName: handleDom.nodeName,
|
|
707
|
+
url: handleDom.url,
|
|
708
|
+
map: handleDom.map,
|
|
709
|
+
findOne,
|
|
710
|
+
findMany,
|
|
711
|
+
closest,
|
|
712
|
+
parent,
|
|
713
|
+
children,
|
|
714
|
+
root,
|
|
715
|
+
remove,
|
|
716
|
+
getCommonAncestor,
|
|
717
|
+
getCommonAncestorFromSelector,
|
|
718
|
+
};
|
|
719
|
+
};
|
|
720
|
+
exports.playwrightLocatorDOMLib = playwrightLocatorDOMLib;
|
|
721
|
+
const _createCommonAncestorFromSelectorFn = (input) => {
|
|
722
|
+
const getCommonAncestorFromSelector = (selector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
723
|
+
const els = [...(yield input.querySelectorAll(selector))];
|
|
724
|
+
if (!els.length)
|
|
725
|
+
return null;
|
|
726
|
+
if (els.length === 1)
|
|
727
|
+
return input.getParent(els[0]);
|
|
728
|
+
const comparerEl = els.shift();
|
|
729
|
+
let ancestorEl = null;
|
|
730
|
+
for (const el of els) {
|
|
731
|
+
const currAncestorEl = comparerEl ? yield input.getCommonAncestor(comparerEl, el) : null;
|
|
732
|
+
const newAncestorEl = !ancestorEl
|
|
733
|
+
? currAncestorEl
|
|
734
|
+
: currAncestorEl && (yield input.isAncestor(currAncestorEl, ancestorEl))
|
|
735
|
+
? currAncestorEl
|
|
736
|
+
: ancestorEl;
|
|
737
|
+
ancestorEl = newAncestorEl;
|
|
738
|
+
}
|
|
739
|
+
return ancestorEl;
|
|
740
|
+
});
|
|
741
|
+
return getCommonAncestorFromSelector;
|
|
742
|
+
};
|
|
743
|
+
//# sourceMappingURL=dom.js.map
|