@roomi-fields/notebooklm-mcp 1.1.2
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/LICENSE +22 -0
- package/README.md +548 -0
- package/dist/auth/auth-manager.d.ts +139 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.js +981 -0
- package/dist/auth/auth-manager.js.map +1 -0
- package/dist/config.d.ts +89 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +216 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/http-wrapper.d.ts +8 -0
- package/dist/http-wrapper.d.ts.map +1 -0
- package/dist/http-wrapper.js +221 -0
- package/dist/http-wrapper.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +499 -0
- package/dist/index.js.map +1 -0
- package/dist/library/notebook-library.d.ts +81 -0
- package/dist/library/notebook-library.d.ts.map +1 -0
- package/dist/library/notebook-library.js +362 -0
- package/dist/library/notebook-library.js.map +1 -0
- package/dist/library/types.d.ts +67 -0
- package/dist/library/types.d.ts.map +1 -0
- package/dist/library/types.js +8 -0
- package/dist/library/types.js.map +1 -0
- package/dist/session/browser-session.d.ts +108 -0
- package/dist/session/browser-session.d.ts.map +1 -0
- package/dist/session/browser-session.js +630 -0
- package/dist/session/browser-session.js.map +1 -0
- package/dist/session/session-manager.d.ts +76 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +273 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/shared-context-manager.d.ts +107 -0
- package/dist/session/shared-context-manager.d.ts.map +1 -0
- package/dist/session/shared-context-manager.js +447 -0
- package/dist/session/shared-context-manager.js.map +1 -0
- package/dist/tools/index.d.ts +225 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +1396 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +133 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +673 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +92 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/page-utils.d.ts +54 -0
- package/dist/utils/page-utils.d.ts.map +1 -0
- package/dist/utils/page-utils.js +422 -0
- package/dist/utils/page-utils.js.map +1 -0
- package/dist/utils/stealth-utils.d.ts +135 -0
- package/dist/utils/stealth-utils.d.ts.map +1 -0
- package/dist/utils/stealth-utils.js +398 -0
- package/dist/utils/stealth-utils.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page utilities for extracting responses from NotebookLM web UI
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to:
|
|
5
|
+
* - Extract latest assistant responses from the page
|
|
6
|
+
* - Wait for new responses with streaming detection
|
|
7
|
+
* - Detect placeholders and loading states
|
|
8
|
+
* - Snapshot existing responses for comparison
|
|
9
|
+
*
|
|
10
|
+
* Based on the Python implementation from page_utils.py
|
|
11
|
+
*/
|
|
12
|
+
import { log } from "./logger.js";
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* CSS selectors to find assistant response elements
|
|
18
|
+
* Ordered by priority (most specific first)
|
|
19
|
+
*/
|
|
20
|
+
const RESPONSE_SELECTORS = [
|
|
21
|
+
".to-user-container .message-text-content",
|
|
22
|
+
"[data-message-author='bot']",
|
|
23
|
+
"[data-message-author='assistant']",
|
|
24
|
+
"[data-message-role='assistant']",
|
|
25
|
+
"[data-author='assistant']",
|
|
26
|
+
"[data-renderer*='assistant']",
|
|
27
|
+
"[data-automation-id='response-text']",
|
|
28
|
+
"[data-automation-id='assistant-response']",
|
|
29
|
+
"[data-automation-id='chat-response']",
|
|
30
|
+
"[data-testid*='assistant']",
|
|
31
|
+
"[data-testid*='response']",
|
|
32
|
+
"[aria-live='polite']",
|
|
33
|
+
"[role='listitem'][data-message-author]",
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Text snippets that indicate a placeholder/loading state
|
|
37
|
+
*/
|
|
38
|
+
const PLACEHOLDER_SNIPPETS = [
|
|
39
|
+
"antwort wird erstellt",
|
|
40
|
+
"answer wird erstellt",
|
|
41
|
+
"answer is being created",
|
|
42
|
+
"answer is being generated",
|
|
43
|
+
"creating answer",
|
|
44
|
+
"generating answer",
|
|
45
|
+
"wird erstellt",
|
|
46
|
+
"getting the context", // NotebookLM initial loading message
|
|
47
|
+
"loading",
|
|
48
|
+
"please wait",
|
|
49
|
+
];
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Helper Functions
|
|
52
|
+
// ============================================================================
|
|
53
|
+
/**
|
|
54
|
+
* Simple string hash function (for efficient comparison)
|
|
55
|
+
*/
|
|
56
|
+
function hashString(str) {
|
|
57
|
+
let hash = 0;
|
|
58
|
+
for (let i = 0; i < str.length; i++) {
|
|
59
|
+
const char = str.charCodeAt(i);
|
|
60
|
+
hash = (hash << 5) - hash + char;
|
|
61
|
+
hash = hash & hash; // Convert to 32bit integer
|
|
62
|
+
}
|
|
63
|
+
return hash;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check if text is a placeholder/loading message
|
|
67
|
+
*/
|
|
68
|
+
function isPlaceholder(text) {
|
|
69
|
+
const lower = text.toLowerCase();
|
|
70
|
+
return PLACEHOLDER_SNIPPETS.some((snippet) => lower.includes(snippet));
|
|
71
|
+
}
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Main Functions
|
|
74
|
+
// ============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Snapshot the latest response text currently visible
|
|
77
|
+
* Returns null if no response found
|
|
78
|
+
*/
|
|
79
|
+
export async function snapshotLatestResponse(page) {
|
|
80
|
+
return await extractLatestText(page, new Set(), false, 0);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Snapshot ALL existing assistant response texts
|
|
84
|
+
* Used to capture visible responses BEFORE submitting a new question
|
|
85
|
+
*/
|
|
86
|
+
export async function snapshotAllResponses(page) {
|
|
87
|
+
const allTexts = [];
|
|
88
|
+
const primarySelector = ".to-user-container";
|
|
89
|
+
try {
|
|
90
|
+
const containers = await page.$$(primarySelector);
|
|
91
|
+
if (containers.length > 0) {
|
|
92
|
+
for (const container of containers) {
|
|
93
|
+
try {
|
|
94
|
+
const textElement = await container.$(".message-text-content");
|
|
95
|
+
if (textElement) {
|
|
96
|
+
const text = await textElement.innerText();
|
|
97
|
+
if (text && text.trim()) {
|
|
98
|
+
allTexts.push(text.trim());
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
log.info(`📸 [SNAPSHOT] Captured ${allTexts.length} existing responses`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
log.warning(`⚠️ [SNAPSHOT] Failed to snapshot responses: ${error}`);
|
|
111
|
+
}
|
|
112
|
+
return allTexts;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Count the number of visible assistant response elements
|
|
116
|
+
*/
|
|
117
|
+
export async function countResponseElements(page) {
|
|
118
|
+
let count = 0;
|
|
119
|
+
for (const selector of RESPONSE_SELECTORS) {
|
|
120
|
+
try {
|
|
121
|
+
const elements = await page.$$(selector);
|
|
122
|
+
if (elements.length > 0) {
|
|
123
|
+
// Count only visible elements
|
|
124
|
+
for (const el of elements) {
|
|
125
|
+
try {
|
|
126
|
+
const isVisible = await el.isVisible();
|
|
127
|
+
if (isVisible) {
|
|
128
|
+
count++;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// If we found elements with this selector, stop trying others
|
|
136
|
+
if (count > 0) {
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return count;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Wait for a new assistant response with streaming detection
|
|
149
|
+
*
|
|
150
|
+
* This function:
|
|
151
|
+
* 1. Polls the page for new response text
|
|
152
|
+
* 2. Detects streaming (text changes) vs. complete (text stable)
|
|
153
|
+
* 3. Requires text to be stable for 3 consecutive polls before returning
|
|
154
|
+
* 4. Ignores placeholders, question echoes, and known responses
|
|
155
|
+
*
|
|
156
|
+
* @param page Playwright page instance
|
|
157
|
+
* @param options Options for waiting
|
|
158
|
+
* @returns The new response text, or null if timeout
|
|
159
|
+
*/
|
|
160
|
+
export async function waitForLatestAnswer(page, options = {}) {
|
|
161
|
+
const { question = "", timeoutMs = 120000, pollIntervalMs = 1000, ignoreTexts = [], debug = false, } = options;
|
|
162
|
+
const deadline = Date.now() + timeoutMs;
|
|
163
|
+
const sanitizedQuestion = question.trim().toLowerCase();
|
|
164
|
+
// Track ALL known texts as HASHES (memory efficient!)
|
|
165
|
+
const knownHashes = new Set();
|
|
166
|
+
for (const text of ignoreTexts) {
|
|
167
|
+
if (typeof text === "string" && text.trim()) {
|
|
168
|
+
knownHashes.add(hashString(text.trim()));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (debug) {
|
|
172
|
+
log.debug(`🔍 [DEBUG] Waiting for NEW answer. Ignoring ${knownHashes.size} known responses`);
|
|
173
|
+
}
|
|
174
|
+
let pollCount = 0;
|
|
175
|
+
let lastCandidate = null;
|
|
176
|
+
let stableCount = 0; // Track how many times we see the same text
|
|
177
|
+
const requiredStablePolls = 8; // Text must be stable for 8 consecutive polls (~8 seconds)
|
|
178
|
+
while (Date.now() < deadline) {
|
|
179
|
+
pollCount++;
|
|
180
|
+
// Extract latest NEW text
|
|
181
|
+
const candidate = await extractLatestText(page, knownHashes, debug, pollCount);
|
|
182
|
+
if (candidate) {
|
|
183
|
+
const normalized = candidate.trim();
|
|
184
|
+
if (normalized) {
|
|
185
|
+
const lower = normalized.toLowerCase();
|
|
186
|
+
// Check if it's a placeholder
|
|
187
|
+
if (isPlaceholder(lower)) {
|
|
188
|
+
if (debug) {
|
|
189
|
+
log.debug(`🔍 [DEBUG] Found placeholder: "${normalized.substring(0, 50)}..." - continuing...`);
|
|
190
|
+
}
|
|
191
|
+
await page.waitForTimeout(250);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
// DEBUG: Log the candidate text to see what we're getting
|
|
195
|
+
if (debug && normalized !== lastCandidate) {
|
|
196
|
+
log.debug(`🔍 [DEBUG] New candidate text (${normalized.length} chars): "${normalized.substring(0, 100)}..."`);
|
|
197
|
+
}
|
|
198
|
+
// Check if it's the question echo
|
|
199
|
+
if (lower === sanitizedQuestion) {
|
|
200
|
+
if (debug) {
|
|
201
|
+
log.debug("🔍 [DEBUG] Found question echo, ignoring");
|
|
202
|
+
}
|
|
203
|
+
knownHashes.add(hashString(normalized)); // Mark as seen
|
|
204
|
+
await page.waitForTimeout(pollIntervalMs);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
// ========================================
|
|
208
|
+
// STREAMING DETECTION: Check if text is stable
|
|
209
|
+
// ========================================
|
|
210
|
+
if (normalized === lastCandidate) {
|
|
211
|
+
// Text hasn't changed - it's stable
|
|
212
|
+
stableCount++;
|
|
213
|
+
if (debug && stableCount === requiredStablePolls) {
|
|
214
|
+
log.debug(`✅ [DEBUG] Text stable for ${stableCount} polls (${normalized.length} chars)`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
// Text changed - streaming in progress
|
|
219
|
+
if (debug && lastCandidate) {
|
|
220
|
+
log.debug(`🔄 [DEBUG] Text changed (${normalized.length} chars, was ${lastCandidate.length})`);
|
|
221
|
+
}
|
|
222
|
+
stableCount = 1;
|
|
223
|
+
lastCandidate = normalized;
|
|
224
|
+
}
|
|
225
|
+
// Only return once text is stable
|
|
226
|
+
if (stableCount >= requiredStablePolls) {
|
|
227
|
+
if (debug) {
|
|
228
|
+
log.debug(`✅ [DEBUG] Returning stable answer (${normalized.length} chars)`);
|
|
229
|
+
}
|
|
230
|
+
return normalized;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
await page.waitForTimeout(pollIntervalMs);
|
|
235
|
+
}
|
|
236
|
+
if (debug) {
|
|
237
|
+
log.debug(`⏱️ [DEBUG] Timeout after ${pollCount} polls`);
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Extract the latest NEW response text from the page
|
|
243
|
+
* Uses hash-based comparison for efficiency
|
|
244
|
+
*
|
|
245
|
+
* @param page Playwright page instance
|
|
246
|
+
* @param knownHashes Set of hashes of already-seen response texts
|
|
247
|
+
* @param debug Enable debug logging
|
|
248
|
+
* @param pollCount Current poll number (for conditional logging)
|
|
249
|
+
* @returns First NEW response text found, or null
|
|
250
|
+
*/
|
|
251
|
+
async function extractLatestText(page, knownHashes, debug, pollCount) {
|
|
252
|
+
// Try the primary selector first (most specific for NotebookLM)
|
|
253
|
+
const primarySelector = ".to-user-container";
|
|
254
|
+
try {
|
|
255
|
+
const containers = await page.$$(primarySelector);
|
|
256
|
+
const totalContainers = containers.length;
|
|
257
|
+
// Early exit if no new containers possible
|
|
258
|
+
if (totalContainers <= knownHashes.size) {
|
|
259
|
+
if (debug && pollCount % 5 === 0) {
|
|
260
|
+
log.dim(`⏭️ [EXTRACT] No new containers (${totalContainers} total, ${knownHashes.size} known)`);
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
if (containers.length > 0) {
|
|
265
|
+
// Only log every 5th poll to reduce noise
|
|
266
|
+
if (debug && pollCount % 5 === 0) {
|
|
267
|
+
log.dim(`🔍 [EXTRACT] Scanning ${totalContainers} containers (${knownHashes.size} known)`);
|
|
268
|
+
}
|
|
269
|
+
let skipped = 0;
|
|
270
|
+
let empty = 0;
|
|
271
|
+
// Scan ALL containers to find the FIRST with NEW text
|
|
272
|
+
for (let idx = 0; idx < containers.length; idx++) {
|
|
273
|
+
const container = containers[idx];
|
|
274
|
+
try {
|
|
275
|
+
const textElement = await container.$(".message-text-content");
|
|
276
|
+
if (textElement) {
|
|
277
|
+
const text = await textElement.innerText();
|
|
278
|
+
if (text && text.trim()) {
|
|
279
|
+
// Hash-based comparison (faster & less memory)
|
|
280
|
+
const textHash = hashString(text.trim());
|
|
281
|
+
if (!knownHashes.has(textHash)) {
|
|
282
|
+
log.success(`✅ [EXTRACT] Found NEW text in container[${idx}]: ${text.trim().length} chars`);
|
|
283
|
+
return text.trim();
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
skipped++;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
empty++;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Only log summary if debug enabled
|
|
299
|
+
if (debug && pollCount % 5 === 0) {
|
|
300
|
+
log.dim(`⏭️ [EXTRACT] No NEW text (skipped ${skipped} known, ${empty} empty)`);
|
|
301
|
+
}
|
|
302
|
+
return null; // Don't fall through to fallback!
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
if (debug) {
|
|
306
|
+
log.warning("⚠️ [EXTRACT] No containers found");
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
log.error(`❌ [EXTRACT] Primary selector failed: ${error}`);
|
|
312
|
+
}
|
|
313
|
+
// Fallback: Try other selectors (only if primary selector failed/found nothing)
|
|
314
|
+
if (debug) {
|
|
315
|
+
log.dim("🔄 [EXTRACT] Trying fallback selectors...");
|
|
316
|
+
}
|
|
317
|
+
for (const selector of RESPONSE_SELECTORS) {
|
|
318
|
+
try {
|
|
319
|
+
const elements = await page.$$(selector);
|
|
320
|
+
if (elements.length === 0)
|
|
321
|
+
continue;
|
|
322
|
+
// Scan ALL elements to find the first with NEW text
|
|
323
|
+
for (const element of elements) {
|
|
324
|
+
try {
|
|
325
|
+
// Prefer full container text when available
|
|
326
|
+
let container = element;
|
|
327
|
+
try {
|
|
328
|
+
const closest = await element.evaluateHandle((el) => {
|
|
329
|
+
return el.closest("[data-message-author], [data-message-role], [data-author], " +
|
|
330
|
+
"[data-testid*='assistant'], [data-automation-id*='response'], article, section");
|
|
331
|
+
});
|
|
332
|
+
if (closest) {
|
|
333
|
+
container = closest.asElement() || element;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
container = element;
|
|
338
|
+
}
|
|
339
|
+
const text = await container.innerText();
|
|
340
|
+
if (text && text.trim() && !knownHashes.has(hashString(text.trim()))) {
|
|
341
|
+
return text.trim();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Final fallback: JavaScript evaluation
|
|
354
|
+
try {
|
|
355
|
+
const fallbackText = await page.evaluate(() => {
|
|
356
|
+
// @ts-expect-error - DOM types available in browser context
|
|
357
|
+
const unique = new Set();
|
|
358
|
+
// @ts-expect-error - DOM types available in browser context
|
|
359
|
+
const isVisible = (el) => {
|
|
360
|
+
// @ts-expect-error - DOM types available in browser context
|
|
361
|
+
if (!el || !el.isConnected)
|
|
362
|
+
return false;
|
|
363
|
+
const rect = el.getBoundingClientRect();
|
|
364
|
+
if (rect.width === 0 || rect.height === 0)
|
|
365
|
+
return false;
|
|
366
|
+
// @ts-expect-error - window available in browser context
|
|
367
|
+
const style = window.getComputedStyle(el);
|
|
368
|
+
if (style.visibility === "hidden" ||
|
|
369
|
+
style.display === "none" ||
|
|
370
|
+
parseFloat(style.opacity || "1") === 0) {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
return true;
|
|
374
|
+
};
|
|
375
|
+
const selectors = [
|
|
376
|
+
"[data-message-author]",
|
|
377
|
+
"[data-message-role]",
|
|
378
|
+
"[data-author]",
|
|
379
|
+
"[data-renderer*='assistant']",
|
|
380
|
+
"[data-testid*='assistant']",
|
|
381
|
+
"[data-automation-id*='response']",
|
|
382
|
+
];
|
|
383
|
+
const candidates = [];
|
|
384
|
+
for (const selector of selectors) {
|
|
385
|
+
// @ts-expect-error - document available in browser context
|
|
386
|
+
for (const el of document.querySelectorAll(selector)) {
|
|
387
|
+
if (!isVisible(el))
|
|
388
|
+
continue;
|
|
389
|
+
if (unique.has(el))
|
|
390
|
+
continue;
|
|
391
|
+
unique.add(el);
|
|
392
|
+
// @ts-expect-error - DOM types available in browser context
|
|
393
|
+
const text = el.innerText || el.textContent || "";
|
|
394
|
+
if (!text.trim())
|
|
395
|
+
continue;
|
|
396
|
+
candidates.push(text.trim());
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (candidates.length > 0) {
|
|
400
|
+
return candidates[candidates.length - 1];
|
|
401
|
+
}
|
|
402
|
+
return null;
|
|
403
|
+
});
|
|
404
|
+
if (typeof fallbackText === "string" && fallbackText.trim()) {
|
|
405
|
+
return fallbackText.trim();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
// Ignore evaluation errors
|
|
410
|
+
}
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
// ============================================================================
|
|
414
|
+
// Exports
|
|
415
|
+
// ============================================================================
|
|
416
|
+
export default {
|
|
417
|
+
snapshotLatestResponse,
|
|
418
|
+
snapshotAllResponses,
|
|
419
|
+
countResponseElements,
|
|
420
|
+
waitForLatestAnswer,
|
|
421
|
+
};
|
|
422
|
+
//# sourceMappingURL=page-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-utils.js","sourceRoot":"","sources":["../../src/utils/page-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth utilities for human-like browser behavior
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to simulate realistic human interactions:
|
|
5
|
+
* - Human-like typing (speed configurable via CONFIG.typingWpmMin/Max)
|
|
6
|
+
* - Realistic mouse movements (Bezier curves with jitter)
|
|
7
|
+
* - Random delays (normal distribution)
|
|
8
|
+
* - Smooth scrolling
|
|
9
|
+
* - Reading pauses
|
|
10
|
+
*
|
|
11
|
+
* Based on the Python implementation from stealth_utils.py
|
|
12
|
+
*/
|
|
13
|
+
import type { Page } from "patchright";
|
|
14
|
+
/**
|
|
15
|
+
* Sleep for specified milliseconds
|
|
16
|
+
*/
|
|
17
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Generate random integer between min and max (inclusive)
|
|
20
|
+
*/
|
|
21
|
+
export declare function randomInt(min: number, max: number): number;
|
|
22
|
+
/**
|
|
23
|
+
* Generate random float between min and max
|
|
24
|
+
*/
|
|
25
|
+
export declare function randomFloat(min: number, max: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Generate random character (for typos)
|
|
28
|
+
*/
|
|
29
|
+
export declare function randomChar(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Generate Gaussian (normal) distributed random number
|
|
32
|
+
* Uses Box-Muller transform
|
|
33
|
+
*/
|
|
34
|
+
export declare function gaussian(mean: number, stdDev: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Add a random delay to simulate human thinking/reaction time
|
|
37
|
+
* Uses normal distribution for more realistic delays
|
|
38
|
+
*
|
|
39
|
+
* @param minMs Minimum delay in milliseconds (default: from CONFIG)
|
|
40
|
+
* @param maxMs Maximum delay in milliseconds (default: from CONFIG)
|
|
41
|
+
*/
|
|
42
|
+
export declare function randomDelay(minMs?: number, maxMs?: number): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Type text in a human-like manner with variable speed and optional typos
|
|
45
|
+
*
|
|
46
|
+
* Simulates realistic typing patterns:
|
|
47
|
+
* - Variable speed (45-65 WPM by default)
|
|
48
|
+
* - Occasional typos (2% chance)
|
|
49
|
+
* - Longer pauses after punctuation
|
|
50
|
+
* - Realistic character delays
|
|
51
|
+
*
|
|
52
|
+
* @param page Playwright page instance
|
|
53
|
+
* @param selector CSS selector of input element
|
|
54
|
+
* @param text Text to type
|
|
55
|
+
* @param options Typing options (wpm, withTypos)
|
|
56
|
+
*/
|
|
57
|
+
export declare function humanType(page: Page, selector: string, text: string, options?: {
|
|
58
|
+
wpm?: number;
|
|
59
|
+
withTypos?: boolean;
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Move mouse in a realistic curved path to target coordinates
|
|
63
|
+
* Uses Bezier-like curves with jitter for natural movement
|
|
64
|
+
*
|
|
65
|
+
* @param page Playwright page instance
|
|
66
|
+
* @param targetX Target X coordinate (default: random)
|
|
67
|
+
* @param targetY Target Y coordinate (default: random)
|
|
68
|
+
* @param steps Number of steps in movement (default: random 10-25)
|
|
69
|
+
*/
|
|
70
|
+
export declare function randomMouseMovement(page: Page, targetX?: number, targetY?: number, steps?: number): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Click an element with realistic human behavior
|
|
73
|
+
* Includes mouse movement, pause, and click
|
|
74
|
+
*
|
|
75
|
+
* @param page Playwright page instance
|
|
76
|
+
* @param selector CSS selector of element to click
|
|
77
|
+
* @param withMouseMovement Whether to move mouse first (default: true)
|
|
78
|
+
*/
|
|
79
|
+
export declare function realisticClick(page: Page, selector: string, withMouseMovement?: boolean): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Scroll the page smoothly like a human
|
|
82
|
+
* Uses multiple small steps for smooth animation
|
|
83
|
+
*
|
|
84
|
+
* @param page Playwright page instance
|
|
85
|
+
* @param amount Scroll amount in pixels (default: random 100-400)
|
|
86
|
+
* @param direction Scroll direction ("down" or "up")
|
|
87
|
+
*/
|
|
88
|
+
export declare function smoothScroll(page: Page, amount?: number, direction?: "up" | "down"): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Pause as if reading text, based on length
|
|
91
|
+
* Calculates realistic reading time based on text length and WPM
|
|
92
|
+
*
|
|
93
|
+
* @param textLength Number of characters to "read"
|
|
94
|
+
* @param wpm Reading speed in words per minute (default: random 200-250)
|
|
95
|
+
*/
|
|
96
|
+
export declare function readingPause(textLength: number, wpm?: number): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Add small random mouse movements to simulate natural fidgeting
|
|
99
|
+
*
|
|
100
|
+
* @param page Playwright page instance
|
|
101
|
+
* @param iterations Number of small movements (default: 3)
|
|
102
|
+
*/
|
|
103
|
+
export declare function randomMouseJitter(page: Page, iterations?: number): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Hover over an element with realistic mouse movement
|
|
106
|
+
*
|
|
107
|
+
* @param page Playwright page instance
|
|
108
|
+
* @param selector CSS selector of element to hover
|
|
109
|
+
*/
|
|
110
|
+
export declare function hoverElement(page: Page, selector: string): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Simulate reading a page with scrolling and pauses
|
|
113
|
+
* Adds realistic behavior of scrolling and reading content
|
|
114
|
+
*
|
|
115
|
+
* @param page Playwright page instance
|
|
116
|
+
*/
|
|
117
|
+
export declare function simulateReadingPage(page: Page): Promise<void>;
|
|
118
|
+
declare const _default: {
|
|
119
|
+
sleep: typeof sleep;
|
|
120
|
+
randomInt: typeof randomInt;
|
|
121
|
+
randomFloat: typeof randomFloat;
|
|
122
|
+
randomChar: typeof randomChar;
|
|
123
|
+
gaussian: typeof gaussian;
|
|
124
|
+
randomDelay: typeof randomDelay;
|
|
125
|
+
humanType: typeof humanType;
|
|
126
|
+
randomMouseMovement: typeof randomMouseMovement;
|
|
127
|
+
realisticClick: typeof realisticClick;
|
|
128
|
+
smoothScroll: typeof smoothScroll;
|
|
129
|
+
readingPause: typeof readingPause;
|
|
130
|
+
randomMouseJitter: typeof randomMouseJitter;
|
|
131
|
+
hoverElement: typeof hoverElement;
|
|
132
|
+
simulateReadingPage: typeof simulateReadingPage;
|
|
133
|
+
};
|
|
134
|
+
export default _default;
|
|
135
|
+
//# sourceMappingURL=stealth-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stealth-utils.d.ts","sourceRoot":"","sources":["../../src/utils/stealth-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAOvC;;GAEG;AACH,wBAAsB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAK7D;AAMD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAsBf;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;CAChB,GACL,OAAO,CAAC,IAAI,CAAC,CAwEf;AAMD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAuCf;AAMD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAc,GAChC,OAAO,CAAC,IAAI,CAAC,CAgCf;AAMD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,GAAE,IAAI,GAAG,MAAe,GAChC,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAMD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBlF;AAMD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,UAAU,GAAE,MAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CAaf;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB9E;AAMD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBnE;;;;;;;;;;;;;;;;;AAMD,wBAeE"}
|