brave-real-browser-mcp-server 2.9.21 → 2.10.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.
@@ -1,6 +1,7 @@
1
1
  // @ts-nocheck
2
2
  import { getPageInstance } from '../browser-manager.js';
3
3
  import axios from 'axios';
4
+ import { sleep } from '../system-utils.js';
4
5
  /**
5
6
  * REST API Endpoint Finder - Discover REST API endpoints
6
7
  */
@@ -46,7 +47,7 @@ export async function handleRESTAPIEndpointFinder(args) {
46
47
  await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
47
48
  }
48
49
  // Wait for additional requests
49
- await page.waitForTimeout(scanDuration);
50
+ await sleep(scanDuration);
50
51
  page.off('request', requestHandler);
51
52
  }
52
53
  // Also scan page content for API endpoints
@@ -1,6 +1,7 @@
1
1
  // @ts-nocheck
2
2
  import { getPageInstance } from '../browser-manager.js';
3
3
  import Tesseract from 'tesseract.js';
4
+ import { sleep } from '../system-utils.js';
4
5
  /**
5
6
  * OCR Engine - Extract text from captcha images using OCR
6
7
  */
@@ -207,7 +208,7 @@ export async function handlePuzzleCaptchaHandler(args) {
207
208
  const stepSize = targetDistance / steps;
208
209
  for (let i = 0; i < steps; i++) {
209
210
  await page.mouse.move(box.x + box.width / 2 + (stepSize * i), box.y + box.height / 2, { steps: 5 });
210
- await page.waitForTimeout(50 + Math.random() * 50); // Random delay for human-like behavior
211
+ await sleep(50 + Math.random() * 50); // Random delay for human-like behavior
211
212
  }
212
213
  await page.mouse.up();
213
214
  result.attemptedSolve = true;
@@ -3,7 +3,7 @@
3
3
  // @ts-nocheck
4
4
  import { getCurrentPage } from '../browser-manager.js';
5
5
  import { validateWorkflow } from '../workflow-validation.js';
6
- import { withErrorHandling } from '../system-utils.js';
6
+ import { withErrorHandling, sleep } from '../system-utils.js';
7
7
  /**
8
8
  * Shadow DOM Extractor - Extract content from Shadow DOM
9
9
  */
@@ -291,11 +291,20 @@ export async function handleFormAutoFill(args) {
291
291
  * AJAX Content Waiter - Wait for dynamic content to load
292
292
  */
293
293
  export async function handleAjaxContentWaiter(args) {
294
- return await withErrorHandling(async () => {
295
- validateWorkflow('ajax_content_waiter', {
294
+ try {
295
+ const validation = validateWorkflow('ajax_content_waiter', {
296
296
  requireBrowser: true,
297
297
  requirePage: true,
298
298
  });
299
+ if (!validation.isValid) {
300
+ return {
301
+ content: [{
302
+ type: 'text',
303
+ text: `⚠️ ${validation.errorMessage || 'Workflow validation failed'}`,
304
+ }],
305
+ isError: true,
306
+ };
307
+ }
299
308
  const page = getCurrentPage();
300
309
  const waitFor = args.waitFor || 'selector'; // selector, xhr, timeout
301
310
  const value = args.value;
@@ -320,7 +329,7 @@ export async function handleAjaxContentWaiter(args) {
320
329
  }
321
330
  }
322
331
  if (waitFor === 'xhr') {
323
- const duration = value || 5000;
332
+ const duration = parseInt(value) || 5000;
324
333
  let xhrCount = 0;
325
334
  const requestHandler = (request) => {
326
335
  if (request.resourceType() === 'xhr' || request.resourceType() === 'fetch') {
@@ -328,8 +337,16 @@ export async function handleAjaxContentWaiter(args) {
328
337
  }
329
338
  };
330
339
  page.on('request', requestHandler);
331
- await page.waitForTimeout(duration);
340
+ await sleep(duration);
332
341
  page.off('request', requestHandler);
342
+ if (xhrCount === 0) {
343
+ return {
344
+ content: [{
345
+ type: 'text',
346
+ text: `ℹ️ Waited ${duration}ms - No XHR/Fetch requests detected.\n\n💡 Note: Monitoring captures NEW requests made during wait period. Page already loaded before monitoring started.`,
347
+ }],
348
+ };
349
+ }
333
350
  return {
334
351
  content: [{
335
352
  type: 'text',
@@ -338,8 +355,8 @@ export async function handleAjaxContentWaiter(args) {
338
355
  };
339
356
  }
340
357
  if (waitFor === 'timeout') {
341
- const duration = value || 3000;
342
- await page.waitForTimeout(duration);
358
+ const duration = parseInt(value) || 3000;
359
+ await sleep(duration);
343
360
  return {
344
361
  content: [{
345
362
  type: 'text',
@@ -347,8 +364,23 @@ export async function handleAjaxContentWaiter(args) {
347
364
  }],
348
365
  };
349
366
  }
350
- throw new Error(`Unknown waitFor type: ${waitFor}`);
351
- }, 'Failed AJAX content waiter');
367
+ return {
368
+ content: [{
369
+ type: 'text',
370
+ text: `❌ Unknown waitFor type: ${waitFor}. Valid types: 'selector', 'xhr', 'timeout'`,
371
+ }],
372
+ isError: true,
373
+ };
374
+ }
375
+ catch (error) {
376
+ return {
377
+ content: [{
378
+ type: 'text',
379
+ text: `❌ AJAX content waiter failed: ${error instanceof Error ? error.message : String(error)}`,
380
+ }],
381
+ isError: true,
382
+ };
383
+ }
352
384
  }
353
385
  /**
354
386
  * Modal Popup Handler - Handle modal popups
@@ -3,7 +3,7 @@
3
3
  // @ts-nocheck
4
4
  import { getCurrentPage } from '../browser-manager.js';
5
5
  import { validateWorkflow } from '../workflow-validation.js';
6
- import { withErrorHandling } from '../system-utils.js';
6
+ import { withErrorHandling, sleep } from '../system-utils.js';
7
7
  import * as xml2js from 'xml2js';
8
8
  /**
9
9
  * "Next" button automatically detect और click करके सभी pages से data collect करता है
@@ -51,14 +51,14 @@ export async function handleAutoPagination(args) {
51
51
  }
52
52
  // Click next button
53
53
  await nextButton.click();
54
- await page.waitForTimeout(waitBetweenPages);
54
+ await sleep(waitBetweenPages);
55
55
  // Wait for navigation or content load
56
56
  try {
57
57
  await page.waitForNavigation({ timeout: 5000, waitUntil: 'domcontentloaded' });
58
58
  }
59
59
  catch (e) {
60
60
  // No navigation occurred, content loaded dynamically
61
- await page.waitForTimeout(1000);
61
+ await sleep(1000);
62
62
  }
63
63
  currentPage++;
64
64
  }
@@ -114,7 +114,7 @@ export async function handleInfiniteScroll(args) {
114
114
  window.scrollTo(0, document.body.scrollHeight);
115
115
  });
116
116
  // Wait for new content to load
117
- await page.waitForTimeout(scrollDelay);
117
+ await sleep(scrollDelay);
118
118
  scrollCount++;
119
119
  }
120
120
  return {
@@ -145,7 +145,7 @@ export async function handleMultiPageScraper(args) {
145
145
  const url = urls[i];
146
146
  try {
147
147
  await page.goto(url, { waitUntil: 'domcontentloaded' });
148
- await page.waitForTimeout(waitBetweenPages);
148
+ await sleep(waitBetweenPages);
149
149
  const pageData = await page.evaluate((selector) => {
150
150
  const elements = document.querySelectorAll(selector);
151
151
  return Array.from(elements).map((el) => ({
@@ -3,7 +3,7 @@
3
3
  // @ts-nocheck
4
4
  import { getCurrentPage } from '../browser-manager.js';
5
5
  import { validateWorkflow } from '../workflow-validation.js';
6
- import { withErrorHandling } from '../system-utils.js';
6
+ import { withErrorHandling, sleep } from '../system-utils.js';
7
7
  /**
8
8
  * HTML Elements Extractor - Extract all HTML elements with complete details
9
9
  */
@@ -203,7 +203,7 @@ export async function handleAjaxExtractor(args) {
203
203
  if (url && page.url() !== url) {
204
204
  await page.goto(url, { waitUntil: 'networkidle2' });
205
205
  }
206
- await page.waitForTimeout(duration);
206
+ await sleep(duration);
207
207
  page.off('request', requestHandler);
208
208
  return {
209
209
  content: [{
@@ -247,7 +247,7 @@ export async function handleFetchXHR(args) {
247
247
  }
248
248
  };
249
249
  page.on('response', responseHandler);
250
- await page.waitForTimeout(duration);
250
+ await sleep(duration);
251
251
  page.off('response', responseHandler);
252
252
  return {
253
253
  content: [{
@@ -296,7 +296,7 @@ export async function handleNetworkRecorder(args) {
296
296
  };
297
297
  page.on('request', requestHandler);
298
298
  page.on('response', responseHandler);
299
- await page.waitForTimeout(duration);
299
+ await sleep(duration);
300
300
  page.off('request', requestHandler);
301
301
  page.off('response', responseHandler);
302
302
  return {
@@ -4,6 +4,7 @@ import * as fs from 'fs/promises';
4
4
  import * as path from 'path';
5
5
  import pixelmatch from 'pixelmatch';
6
6
  import { PNG } from 'pngjs';
7
+ import { sleep } from '../system-utils.js';
7
8
  /**
8
9
  * Full Page Screenshot - Capture entire page
9
10
  */
@@ -236,7 +237,7 @@ export async function handleVideoRecording(args) {
236
237
  const framePath = path.join(framesDir, `frame_${i.toString().padStart(4, '0')}.png`);
237
238
  await page.screenshot({ path: framePath });
238
239
  frames.push(framePath);
239
- await page.waitForTimeout(frameDelay);
240
+ await sleep(frameDelay);
240
241
  }
241
242
  }
242
243
  return {