@olib-ai/owl-browser-sdk 1.2.1 → 1.2.3
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 +338 -3
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +50 -7
- package/dist/connection.js.map +1 -1
- package/dist/context.d.ts +476 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +708 -0
- package/dist/context.js.map +1 -1
- package/dist/errors.d.ts +104 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +149 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +129 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -267,6 +267,126 @@ await page.type('640x400', 'text here'); // Type at position
|
|
|
267
267
|
await page.highlight('login button');
|
|
268
268
|
```
|
|
269
269
|
|
|
270
|
+
#### Advanced Interactions
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Hover over elements (for tooltips, dropdowns)
|
|
274
|
+
await page.hover('menu item');
|
|
275
|
+
await page.hover('.dropdown-trigger', 500); // hover for 500ms
|
|
276
|
+
|
|
277
|
+
// Double-click
|
|
278
|
+
await page.doubleClick('editable cell');
|
|
279
|
+
|
|
280
|
+
// Right-click (context menu)
|
|
281
|
+
await page.rightClick('file item');
|
|
282
|
+
|
|
283
|
+
// Clear input before typing
|
|
284
|
+
await page.clearInput('search box');
|
|
285
|
+
await page.type('search box', 'new search');
|
|
286
|
+
|
|
287
|
+
// Focus and blur (trigger validation)
|
|
288
|
+
await page.focus('email input');
|
|
289
|
+
await page.blur('email input');
|
|
290
|
+
|
|
291
|
+
// Select all text in input
|
|
292
|
+
await page.selectAll('text area');
|
|
293
|
+
|
|
294
|
+
// Keyboard combinations
|
|
295
|
+
await page.keyboardCombo('a', ['ctrl']); // Ctrl+A (select all)
|
|
296
|
+
await page.keyboardCombo('c', ['ctrl']); // Ctrl+C (copy)
|
|
297
|
+
await page.keyboardCombo('v', ['ctrl']); // Ctrl+V (paste)
|
|
298
|
+
await page.keyboardCombo('z', ['ctrl']); // Ctrl+Z (undo)
|
|
299
|
+
await page.keyboardCombo('s', ['ctrl', 'shift']); // Ctrl+Shift+S
|
|
300
|
+
|
|
301
|
+
// Human-like mouse movement (anti-bot detection)
|
|
302
|
+
await page.mouseMove(100, 100, 500, 300); // Move from (100,100) to (500,300)
|
|
303
|
+
await page.mouseMove(100, 100, 500, 300, 50); // With 50 intermediate steps
|
|
304
|
+
await page.mouseMove(100, 100, 500, 300, 0, [ // With stop points
|
|
305
|
+
[200, 150],
|
|
306
|
+
[350, 250]
|
|
307
|
+
]);
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
#### Element State Checks
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
// Check visibility
|
|
314
|
+
if (await page.isVisible('error message')) {
|
|
315
|
+
console.log('Error displayed');
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Check if enabled/disabled
|
|
319
|
+
if (await page.isEnabled('submit button')) {
|
|
320
|
+
await page.click('submit button');
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Check checkbox/radio state
|
|
324
|
+
const isChecked = await page.isChecked('remember me checkbox');
|
|
325
|
+
|
|
326
|
+
// Get element attribute
|
|
327
|
+
const href = await page.getAttribute('a.link', 'href');
|
|
328
|
+
const placeholder = await page.getAttribute('input', 'placeholder');
|
|
329
|
+
|
|
330
|
+
// Get element position and size
|
|
331
|
+
const box = await page.getBoundingBox('header');
|
|
332
|
+
console.log(`Position: ${box.x}, ${box.y}`);
|
|
333
|
+
console.log(`Size: ${box.width} x ${box.height}`);
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### File Upload
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
// Upload single file
|
|
340
|
+
await page.uploadFile('input[type="file"]', ['/path/to/document.pdf']);
|
|
341
|
+
|
|
342
|
+
// Upload multiple files
|
|
343
|
+
await page.uploadFile('file input', [
|
|
344
|
+
'/path/to/image1.jpg',
|
|
345
|
+
'/path/to/image2.jpg'
|
|
346
|
+
]);
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### Frame/Iframe Handling
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
// List all frames on the page
|
|
353
|
+
const frames = await page.listFrames();
|
|
354
|
+
for (const frame of frames) {
|
|
355
|
+
console.log(`Frame: ${frame.name || frame.id} - ${frame.url}`);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Switch to iframe by selector
|
|
359
|
+
await page.switchToFrame('#payment-iframe');
|
|
360
|
+
|
|
361
|
+
// Or by frame name/id
|
|
362
|
+
await page.switchToFrame('checkout-frame');
|
|
363
|
+
|
|
364
|
+
// Interact with elements inside iframe
|
|
365
|
+
await page.type('card number input', '4111111111111111');
|
|
366
|
+
await page.click('submit payment');
|
|
367
|
+
|
|
368
|
+
// Switch back to main frame
|
|
369
|
+
await page.switchToMainFrame();
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
#### JavaScript Evaluation
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
// Execute JavaScript in page context
|
|
376
|
+
const title = await page.evaluate<string>('document.title');
|
|
377
|
+
|
|
378
|
+
// With arguments
|
|
379
|
+
const text = await page.evaluate<string>(
|
|
380
|
+
'(selector) => document.querySelector(selector)?.textContent',
|
|
381
|
+
['h1']
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
// Return complex objects
|
|
385
|
+
const metrics = await page.evaluate<{width: number, height: number}>(
|
|
386
|
+
'() => ({ width: window.innerWidth, height: window.innerHeight })'
|
|
387
|
+
);
|
|
388
|
+
```
|
|
389
|
+
|
|
270
390
|
#### Content Extraction
|
|
271
391
|
|
|
272
392
|
```typescript
|
|
@@ -573,6 +693,116 @@ const viewport: Viewport = await page.getViewport();
|
|
|
573
693
|
| Built-in Ad Blocking | ✅ 72 domains | ❌ Manual setup |
|
|
574
694
|
| Maintenance Overhead | ✅ Low (AI handles changes) | ⚠️ High (selectors break) |
|
|
575
695
|
|
|
696
|
+
### Network Interception
|
|
697
|
+
|
|
698
|
+
Block, mock, or redirect network requests:
|
|
699
|
+
|
|
700
|
+
```typescript
|
|
701
|
+
// Block ads
|
|
702
|
+
const ruleId = await page.addNetworkRule({
|
|
703
|
+
urlPattern: 'https://ads.example.com/*',
|
|
704
|
+
action: 'block'
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
// Mock API response
|
|
708
|
+
await page.addNetworkRule({
|
|
709
|
+
urlPattern: 'https://api.example.com/data',
|
|
710
|
+
action: 'mock',
|
|
711
|
+
mockBody: '{"status": "ok"}',
|
|
712
|
+
mockStatus: 200,
|
|
713
|
+
mockContentType: 'application/json'
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
// Redirect requests
|
|
717
|
+
await page.addNetworkRule({
|
|
718
|
+
urlPattern: 'https://old-api.example.com/*',
|
|
719
|
+
action: 'redirect',
|
|
720
|
+
redirectUrl: 'https://new-api.example.com/'
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
// Enable interception
|
|
724
|
+
await page.setNetworkInterception(true);
|
|
725
|
+
|
|
726
|
+
// Get network log
|
|
727
|
+
const log = await page.getNetworkLog();
|
|
728
|
+
|
|
729
|
+
// Remove rule
|
|
730
|
+
await page.removeNetworkRule(ruleId);
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
### File Downloads
|
|
734
|
+
|
|
735
|
+
Handle file downloads:
|
|
736
|
+
|
|
737
|
+
```typescript
|
|
738
|
+
// Set download directory
|
|
739
|
+
await page.setDownloadPath('/tmp/downloads');
|
|
740
|
+
|
|
741
|
+
// Click a download link
|
|
742
|
+
await page.click('a[download]');
|
|
743
|
+
|
|
744
|
+
// Wait for download to complete
|
|
745
|
+
const download = await page.waitForDownload();
|
|
746
|
+
console.log(`Downloaded: ${download.filename} to ${download.path}`);
|
|
747
|
+
|
|
748
|
+
// Or get all downloads
|
|
749
|
+
const downloads = await page.getDownloads();
|
|
750
|
+
|
|
751
|
+
// Cancel a download
|
|
752
|
+
await page.cancelDownload(download.id);
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### Dialog Handling
|
|
756
|
+
|
|
757
|
+
Handle JavaScript dialogs (alert, confirm, prompt):
|
|
758
|
+
|
|
759
|
+
```typescript
|
|
760
|
+
// Auto-accept alerts
|
|
761
|
+
await page.setDialogAction('alert', 'accept');
|
|
762
|
+
|
|
763
|
+
// Auto-respond to prompts
|
|
764
|
+
await page.setDialogAction('prompt', 'accept_with_text', 'My answer');
|
|
765
|
+
|
|
766
|
+
// Dismiss confirms
|
|
767
|
+
await page.setDialogAction('confirm', 'dismiss');
|
|
768
|
+
|
|
769
|
+
// Or handle manually
|
|
770
|
+
const dialog = await page.waitForDialog();
|
|
771
|
+
console.log(`Dialog message: ${dialog.message}`);
|
|
772
|
+
await page.handleDialog(dialog.id, true, 'response text');
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### Multi-Tab Management
|
|
776
|
+
|
|
777
|
+
Work with multiple tabs:
|
|
778
|
+
|
|
779
|
+
```typescript
|
|
780
|
+
// Create new tab
|
|
781
|
+
const tab = await page.newTab('https://google.com');
|
|
782
|
+
console.log(`Tab ID: ${tab.tabId}`);
|
|
783
|
+
|
|
784
|
+
// List all tabs
|
|
785
|
+
const tabs = await page.getTabs();
|
|
786
|
+
|
|
787
|
+
// Switch to a tab
|
|
788
|
+
await page.switchTab(tabs[0].tabId);
|
|
789
|
+
|
|
790
|
+
// Get active tab
|
|
791
|
+
const active = await page.getActiveTab();
|
|
792
|
+
|
|
793
|
+
// Get tab count
|
|
794
|
+
const count = await page.getTabCount();
|
|
795
|
+
|
|
796
|
+
// Close a tab
|
|
797
|
+
await page.closeTab(tab.tabId);
|
|
798
|
+
|
|
799
|
+
// Configure popup handling
|
|
800
|
+
await page.setPopupPolicy('block'); // 'allow', 'block', 'new_tab', 'background'
|
|
801
|
+
|
|
802
|
+
// Get blocked popups
|
|
803
|
+
const blocked = await page.getBlockedPopups();
|
|
804
|
+
```
|
|
805
|
+
|
|
576
806
|
## Advanced Features
|
|
577
807
|
|
|
578
808
|
### Semantic Element Matching
|
|
@@ -622,7 +852,12 @@ import {
|
|
|
622
852
|
RateLimitError,
|
|
623
853
|
IPBlockedError,
|
|
624
854
|
LicenseError,
|
|
625
|
-
BrowserInitializationError
|
|
855
|
+
BrowserInitializationError,
|
|
856
|
+
ActionError,
|
|
857
|
+
ActionStatus,
|
|
858
|
+
ElementNotFoundError,
|
|
859
|
+
NavigationError,
|
|
860
|
+
FirewallError
|
|
626
861
|
} from '@olib-ai/owl-browser-sdk';
|
|
627
862
|
|
|
628
863
|
async function withErrorHandling() {
|
|
@@ -641,9 +876,34 @@ async function withErrorHandling() {
|
|
|
641
876
|
await page.goto('https://example.com');
|
|
642
877
|
|
|
643
878
|
// Your automation code...
|
|
879
|
+
await page.click('non-existent button');
|
|
644
880
|
|
|
645
881
|
} catch (error) {
|
|
646
|
-
if (error instanceof
|
|
882
|
+
if (error instanceof ElementNotFoundError) {
|
|
883
|
+
// Element was not found on the page
|
|
884
|
+
console.error('Element not found:', error.message);
|
|
885
|
+
} else if (error instanceof NavigationError) {
|
|
886
|
+
// Navigation failed (timeout, page load error, etc.)
|
|
887
|
+
console.error('Navigation failed:', error.message);
|
|
888
|
+
} else if (error instanceof ActionError) {
|
|
889
|
+
// Generic action error with detailed status
|
|
890
|
+
console.error('Action failed:', error.message);
|
|
891
|
+
console.error('Status:', error.status);
|
|
892
|
+
console.error('Selector:', error.selector);
|
|
893
|
+
// Check specific error types
|
|
894
|
+
if (error.isElementNotFound()) {
|
|
895
|
+
console.error('Could not find element');
|
|
896
|
+
} else if (error.isNavigationError()) {
|
|
897
|
+
console.error('Navigation issue');
|
|
898
|
+
} else if (error.isTimeout()) {
|
|
899
|
+
console.error('Operation timed out');
|
|
900
|
+
}
|
|
901
|
+
} else if (error instanceof FirewallError) {
|
|
902
|
+
// Web firewall/bot protection detected
|
|
903
|
+
console.error('Firewall detected:', error.provider);
|
|
904
|
+
console.error('Challenge type:', error.challengeType);
|
|
905
|
+
console.error('URL:', error.url);
|
|
906
|
+
} else if (error instanceof AuthenticationError) {
|
|
647
907
|
// 401 - Invalid or expired token
|
|
648
908
|
console.error('Auth failed:', error.message);
|
|
649
909
|
console.error('Reason:', error.reason);
|
|
@@ -665,17 +925,92 @@ async function withErrorHandling() {
|
|
|
665
925
|
}
|
|
666
926
|
```
|
|
667
927
|
|
|
928
|
+
### Action Result Validation
|
|
929
|
+
|
|
930
|
+
The browser returns structured `ActionResult` responses for browser actions, providing detailed information about success or failure:
|
|
931
|
+
|
|
932
|
+
```typescript
|
|
933
|
+
import {
|
|
934
|
+
ActionStatus,
|
|
935
|
+
ActionResult,
|
|
936
|
+
ActionError,
|
|
937
|
+
isActionResult,
|
|
938
|
+
throwIfActionFailed
|
|
939
|
+
} from '@olib-ai/owl-browser-sdk';
|
|
940
|
+
|
|
941
|
+
// ActionStatus enum values
|
|
942
|
+
ActionStatus.OK // Action succeeded
|
|
943
|
+
ActionStatus.ELEMENT_NOT_FOUND // Element not found on page
|
|
944
|
+
ActionStatus.ELEMENT_NOT_VISIBLE // Element exists but not visible
|
|
945
|
+
ActionStatus.ELEMENT_NOT_INTERACTABLE // Element not interactable
|
|
946
|
+
ActionStatus.NAVIGATION_FAILED // Navigation failed
|
|
947
|
+
ActionStatus.NAVIGATION_TIMEOUT // Navigation timed out
|
|
948
|
+
ActionStatus.PAGE_LOAD_ERROR // Page failed to load
|
|
949
|
+
ActionStatus.FIREWALL_DETECTED // Web firewall/bot protection detected
|
|
950
|
+
ActionStatus.CAPTCHA_DETECTED // CAPTCHA challenge detected
|
|
951
|
+
ActionStatus.CLICK_FAILED // Click action failed
|
|
952
|
+
ActionStatus.TYPE_FAILED // Type action failed
|
|
953
|
+
ActionStatus.CONTEXT_NOT_FOUND // Browser context not found
|
|
954
|
+
ActionStatus.INVALID_SELECTOR // Invalid selector provided
|
|
955
|
+
ActionStatus.TIMEOUT // Operation timed out
|
|
956
|
+
|
|
957
|
+
// ActionResult interface
|
|
958
|
+
interface ActionResult {
|
|
959
|
+
success: boolean;
|
|
960
|
+
status: ActionStatus | string;
|
|
961
|
+
message: string;
|
|
962
|
+
selector?: string; // The selector that failed (for element errors)
|
|
963
|
+
url?: string; // URL involved (for navigation errors)
|
|
964
|
+
http_status?: number; // HTTP status code (for navigation)
|
|
965
|
+
error_code?: string; // Browser error code
|
|
966
|
+
element_count?: number; // Elements found (for multiple_elements error)
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// Helper functions
|
|
970
|
+
if (isActionResult(result)) {
|
|
971
|
+
if (!result.success) {
|
|
972
|
+
throwIfActionFailed(result); // Throws appropriate exception
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
```
|
|
976
|
+
|
|
668
977
|
### Exception Types
|
|
669
978
|
|
|
670
979
|
| Exception | HTTP Code | Description |
|
|
671
980
|
|-----------|-----------|-------------|
|
|
981
|
+
| `ActionError` | - | Browser action failed with status code and details |
|
|
982
|
+
| `ElementNotFoundError` | - | Element not found on page |
|
|
983
|
+
| `NavigationError` | - | Navigation failed (timeout, load error) |
|
|
984
|
+
| `FirewallError` | - | Web firewall/bot protection detected (Cloudflare, Akamai, etc.) |
|
|
985
|
+
| `ContextError` | - | Browser context not found |
|
|
672
986
|
| `AuthenticationError` | 401 | Invalid/expired token or JWT signature mismatch |
|
|
673
987
|
| `RateLimitError` | 429 | Too many requests, includes `retryAfter` in seconds |
|
|
674
988
|
| `IPBlockedError` | 403 | Client IP not in whitelist |
|
|
675
989
|
| `LicenseError` | 503 | Browser license validation failed |
|
|
676
990
|
| `BrowserInitializationError` | - | Failed to start/connect to browser |
|
|
677
991
|
| `CommandTimeoutError` | - | Operation timed out |
|
|
678
|
-
|
|
992
|
+
|
|
993
|
+
### FirewallError Properties
|
|
994
|
+
|
|
995
|
+
| Property | Type | Description |
|
|
996
|
+
|----------|------|-------------|
|
|
997
|
+
| `url` | `string` | The URL where the firewall was detected |
|
|
998
|
+
| `provider` | `string` | Firewall provider (Cloudflare, Akamai, Imperva, etc.) |
|
|
999
|
+
| `challengeType` | `string?` | Type of challenge (JS Challenge, CAPTCHA, etc.) |
|
|
1000
|
+
|
|
1001
|
+
The browser automatically detects web firewalls including Cloudflare, Akamai, Imperva, PerimeterX, DataDome, and AWS WAF.
|
|
1002
|
+
|
|
1003
|
+
### ActionError Properties
|
|
1004
|
+
|
|
1005
|
+
| Property | Type | Description |
|
|
1006
|
+
|----------|------|-------------|
|
|
1007
|
+
| `status` | `ActionStatus` | Status code (e.g., `element_not_found`) |
|
|
1008
|
+
| `message` | `string` | Human-readable error message |
|
|
1009
|
+
| `selector` | `string?` | The selector that failed |
|
|
1010
|
+
| `url` | `string?` | URL involved in navigation errors |
|
|
1011
|
+
| `httpStatus` | `number?` | HTTP status code |
|
|
1012
|
+
| `errorCode` | `string?` | Browser error code |
|
|
1013
|
+
| `elementCount` | `number?` | Number of elements found |
|
|
679
1014
|
|
|
680
1015
|
## Performance Tips
|
|
681
1016
|
|
package/dist/connection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EAAE,aAAa,EAA6E,MAAM,SAAS,CAAC;AAexH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;CACtB;AAmKD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gCAAgC;IAChC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,4CAA4C;IAC5C,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAExE,8BAA8B;IAC9B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,wCAAwC;IACxC,SAAS,IAAI,OAAO,CAAC;CACtB;AA0BD;;GAEG;AACH,qBAAa,eAAgB,YAAW,iBAAiB;IACvD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAU;IAGzB,OAAO,CAAC,YAAY,CAA2D;IAC/E,OAAO,CAAC,mBAAmB,CAAuB;gBAEtC,MAAM,EAAE,aAAa;IAOjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8BnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiHjC;;OAEG;IACH,OAAO,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/connection.js
CHANGED
|
@@ -350,7 +350,31 @@ class LocalConnection {
|
|
|
350
350
|
pending.reject(new Error(response.error));
|
|
351
351
|
}
|
|
352
352
|
else {
|
|
353
|
-
|
|
353
|
+
// Check for ActionResult format (has success property)
|
|
354
|
+
// ActionResult: {"success": bool, "status": "code", "message": "...", ...}
|
|
355
|
+
const result = response.result;
|
|
356
|
+
if (result && typeof result === 'object' && 'success' in result) {
|
|
357
|
+
if (!result.success) {
|
|
358
|
+
// Create detailed error with status code and message
|
|
359
|
+
const errorMsg = result.message || `Action failed: ${result.status || 'unknown'}`;
|
|
360
|
+
const error = new Error(errorMsg);
|
|
361
|
+
error.status = result.status;
|
|
362
|
+
error.selector = result.selector;
|
|
363
|
+
error.url = result.url;
|
|
364
|
+
error.httpStatus = result.http_status;
|
|
365
|
+
error.errorCode = result.error_code;
|
|
366
|
+
error.elementCount = result.element_count;
|
|
367
|
+
pending.reject(error);
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
// Success - resolve with the full result for detailed info
|
|
371
|
+
pending.resolve(result);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
// Legacy format - resolve as-is
|
|
376
|
+
pending.resolve(result);
|
|
377
|
+
}
|
|
354
378
|
}
|
|
355
379
|
}
|
|
356
380
|
}
|
|
@@ -714,6 +738,11 @@ class HttpConnection {
|
|
|
714
738
|
// Homepage is a local-only feature, return empty for HTTP mode
|
|
715
739
|
return '';
|
|
716
740
|
}
|
|
741
|
+
if (method === 'waitForNavigation') {
|
|
742
|
+
// waitForNavigation is not needed in HTTP mode - browser_navigate is synchronous
|
|
743
|
+
// Just return success
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
717
746
|
const tool = this.mapMethodToTool(method);
|
|
718
747
|
const mappedParams = this.mapParams(method, params);
|
|
719
748
|
if (this.verbose) {
|
|
@@ -725,17 +754,31 @@ class HttpConnection {
|
|
|
725
754
|
if (!response.success) {
|
|
726
755
|
throw new Error(response.error || 'Unknown error');
|
|
727
756
|
}
|
|
757
|
+
// Unwrap nested IPC response format
|
|
758
|
+
// HTTP server wraps browser IPC responses: {success: true, result: {id: N, result: value}}
|
|
759
|
+
// We need to extract the inner 'result' value
|
|
760
|
+
let result = response.result;
|
|
761
|
+
if (result && typeof result === 'object' && 'id' in result && 'result' in result) {
|
|
762
|
+
result = result.result;
|
|
763
|
+
}
|
|
728
764
|
// Handle special return value transformations
|
|
765
|
+
if (method === 'createContext') {
|
|
766
|
+
// createContext result is the context ID string (e.g., 'ctx_000001')
|
|
767
|
+
return result;
|
|
768
|
+
}
|
|
729
769
|
if (method === 'getCurrentURL' || method === 'getPageTitle') {
|
|
730
770
|
// These methods call getPageInfo but need specific fields
|
|
731
|
-
if (
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
771
|
+
if (typeof result === 'object' && result !== null) {
|
|
772
|
+
if (method === 'getCurrentURL') {
|
|
773
|
+
return result.url || result;
|
|
774
|
+
}
|
|
775
|
+
if (method === 'getPageTitle') {
|
|
776
|
+
return result.title || result;
|
|
777
|
+
}
|
|
736
778
|
}
|
|
779
|
+
return result;
|
|
737
780
|
}
|
|
738
|
-
return
|
|
781
|
+
return result;
|
|
739
782
|
}, this.retryConfig, (error, attempt, delayMs) => {
|
|
740
783
|
if (this.verbose) {
|
|
741
784
|
console.error(`[HTTP] Retry ${attempt}/${this.retryConfig.maxRetries} for ${tool} after ${delayMs}ms: ${error.message}`);
|