@ohos-ports/vibium 26.5.31-beta.2 → 26.5.31-beta.4
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/dist/bidi-bridge.js +241 -31
- package/dist/index.js +4 -4
- package/dist/index.mjs +4 -4
- package/dist/worker.js +4 -4
- package/package.json +1 -1
- package/README.md +0 -72
package/dist/bidi-bridge.js
CHANGED
|
@@ -19,6 +19,11 @@ let mainSessionId = null;
|
|
|
19
19
|
let pageSessions = {};
|
|
20
20
|
let bidiWs = null; // Active BiDi WebSocket (for event forwarding)
|
|
21
21
|
let subscribedEvents = new Set();
|
|
22
|
+
let executionContexts = {};
|
|
23
|
+
let sharedIdMap = new Map();
|
|
24
|
+
let sharedIdCounter = 0;
|
|
25
|
+
let pageLoadCallbacks = new Map();
|
|
26
|
+
let pendingPreloadScripts = [];
|
|
22
27
|
|
|
23
28
|
// ─── CDP helpers ─────────────────────────────────────
|
|
24
29
|
function cdpSend(method, params = {}, sessionId) {
|
|
@@ -67,6 +72,32 @@ function handleCDPEvent(msg) {
|
|
|
67
72
|
break;
|
|
68
73
|
case 'Page.loadEventFired':
|
|
69
74
|
sendBiDiEvent('browsingContext.load', { context: ctx });
|
|
75
|
+
{ var cb = pageLoadCallbacks.get(sid) || pageLoadCallbacks.get(ctx); if (cb) { pageLoadCallbacks.delete(sid); pageLoadCallbacks.delete(ctx); cb(); } }
|
|
76
|
+
break;
|
|
77
|
+
case 'Page.domContentEventFired':
|
|
78
|
+
sendBiDiEvent('browsingContext.domContentLoaded', { context: ctx });
|
|
79
|
+
{ var cb2 = pageLoadCallbacks.get(sid) || pageLoadCallbacks.get(ctx); if (cb2) { pageLoadCallbacks.delete(sid); pageLoadCallbacks.delete(ctx); cb2(); } }
|
|
80
|
+
break;
|
|
81
|
+
case 'Target.targetCreated':
|
|
82
|
+
if (params.targetInfo && params.targetInfo.type === 'page') {
|
|
83
|
+
var tcCtx = params.targetInfo.targetId;
|
|
84
|
+
var tcData = { context: tcCtx };
|
|
85
|
+
if (params.targetInfo.openerId) tcData.originalOpener = params.targetInfo.openerId;
|
|
86
|
+
sendBiDiEvent('browsingContext.contextCreated', tcData);
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
case 'Target.targetDestroyed':
|
|
90
|
+
if (params.targetInfo) sendBiDiEvent('browsingContext.contextClosed', { context: params.targetInfo.targetId });
|
|
91
|
+
break;
|
|
92
|
+
case 'Page.javascriptDialogOpening':
|
|
93
|
+
cdpSend('Page.handleJavaScriptDialog', { accept: true }, sid || mainSessionId).catch(function(){});
|
|
94
|
+
sendBiDiEvent('browsingContext.userPromptOpened', { context: ctx, type: params.type, message: params.message });
|
|
95
|
+
break;
|
|
96
|
+
case 'Runtime.consoleAPICalled':
|
|
97
|
+
{ var typeMap = {log:'log',warning:'warn',error:'error',info:'info',debug:'debug',trace:'log',dir:'log'}; var ct = typeMap[params.type] || 'log'; var cargs = (params.args || []).map(function(a) { return a.value !== undefined ? a.value : (a.description || ''); }); sendBiDiEvent('log.entryAdded', { context: ctx, type: ct, args: cargs, text: cargs.join(' '), level: ct === 'error' ? 'error' : (ct === 'warn' ? 'warning' : 'info') }); }
|
|
98
|
+
break;
|
|
99
|
+
case 'Runtime.exceptionThrown':
|
|
100
|
+
{ var exd = params.exceptionDetails || {}; sendBiDiEvent('log.entryAdded', { context: ctx, type: 'error', text: exd.text || 'Uncaught exception', level: 'error' }); }
|
|
70
101
|
break;
|
|
71
102
|
case 'Page.domContentEventFired':
|
|
72
103
|
sendBiDiEvent('browsingContext.domContentLoaded', { context: ctx });
|
|
@@ -208,6 +239,8 @@ async function initCDP() {
|
|
|
208
239
|
pageSessions[mainContextId] = { targetId: mainContextId, sessionId: mainSessionId };
|
|
209
240
|
await cdpSend('Page.enable', {}, mainSessionId).catch(() => {});
|
|
210
241
|
await cdpSend('Runtime.enable', {}, mainSessionId).catch(() => {});
|
|
242
|
+
await cdpSend('Network.enable', {}, mainSessionId).catch(() => {});
|
|
243
|
+
await cdpSend('Target.setDiscoverTargets', { discover: true }, mainSessionId).catch(() => {});
|
|
211
244
|
console.log(`[bridge] Ready: ctx=${mainContextId}, session=${mainSessionId}`);
|
|
212
245
|
resolve();
|
|
213
246
|
} catch (e) {
|
|
@@ -223,6 +256,34 @@ async function initCDP() {
|
|
|
223
256
|
});
|
|
224
257
|
}
|
|
225
258
|
|
|
259
|
+
async function ensureSession(ctx) {
|
|
260
|
+
if (!pageSessions[ctx] && ctx && ctx !== mainContextId) {
|
|
261
|
+
try {
|
|
262
|
+
var targets = await cdpSend('Target.getTargets');
|
|
263
|
+
var target = (targets.targetInfos || []).find(function(t) { return t.targetId === ctx; });
|
|
264
|
+
if (target) {
|
|
265
|
+
var att = await cdpSend('Target.attachToTarget', { targetId: ctx, flatten: true });
|
|
266
|
+
pageSessions[ctx] = { targetId: ctx, sessionId: att.sessionId };
|
|
267
|
+
await cdpSend('Page.enable', {}, att.sessionId).catch(function(){});
|
|
268
|
+
await cdpSend('Runtime.enable', {}, att.sessionId).catch(function(){});
|
|
269
|
+
await cdpSend('Network.enable', {}, att.sessionId).catch(function(){});
|
|
270
|
+
for (var ps of pendingPreloadScripts) {
|
|
271
|
+
try { await cdpSend('Page.addScriptToEvaluateOnNewDocument', { source: ps }, att.sessionId); } catch(e) {}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
} catch(e) {}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async function discoverAllSessions() {
|
|
278
|
+
try {
|
|
279
|
+
var targets = await cdpSend('Target.getTargets');
|
|
280
|
+
for (var t of (targets.targetInfos || [])) {
|
|
281
|
+
if (t.type === 'page' && !pageSessions[t.targetId] && t.targetId !== mainContextId) {
|
|
282
|
+
await ensureSession(t.targetId);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
} catch(e) {}
|
|
286
|
+
}
|
|
226
287
|
function getSession(context) {
|
|
227
288
|
return pageSessions[context]?.sessionId || mainSessionId;
|
|
228
289
|
}
|
|
@@ -291,17 +352,16 @@ async function handleBiDi(msg) {
|
|
|
291
352
|
}
|
|
292
353
|
|
|
293
354
|
case 'session.end': {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
await cdpSend('Target.
|
|
355
|
+
console.log('[bridge] session.end -> cleaning up (keeping main session)');
|
|
356
|
+
for (var seCtx in pageSessions) {
|
|
357
|
+
if (seCtx !== mainContextId) {
|
|
358
|
+
try { await cdpSend('Target.closeTarget', { targetId: seCtx }); } catch(e) {}
|
|
359
|
+
try { await cdpSend('Target.detachFromTarget', { sessionId: pageSessions[seCtx].sessionId }); } catch(e) {}
|
|
360
|
+
delete pageSessions[seCtx];
|
|
299
361
|
}
|
|
300
|
-
await cdpSend('Target.detachFromTarget', { sessionId: info.sessionId }).catch(() => {});
|
|
301
362
|
}
|
|
302
|
-
// Disable domains that were enabled for events
|
|
303
|
-
await cdpSend('Network.disable', {}, mainSessionId).catch(() => {});
|
|
304
363
|
subscribedEvents.clear();
|
|
364
|
+
pendingPreloadScripts = [];
|
|
305
365
|
result = {};
|
|
306
366
|
break;
|
|
307
367
|
}
|
|
@@ -341,9 +401,16 @@ async function handleBiDi(msg) {
|
|
|
341
401
|
}
|
|
342
402
|
|
|
343
403
|
case 'browsingContext.navigate': {
|
|
344
|
-
const
|
|
345
|
-
const
|
|
346
|
-
const nav = await cdpSend('Page.navigate', { url: params.url },
|
|
404
|
+
const navCtx = params.context || mainContextId;
|
|
405
|
+
const navSid = getSession(navCtx);
|
|
406
|
+
const nav = await cdpSend('Page.navigate', { url: params.url }, navSid);
|
|
407
|
+
let loadResolve;
|
|
408
|
+
const loadPromise = new Promise(function(r) { loadResolve = r; });
|
|
409
|
+
pageLoadCallbacks.set(navSid, loadResolve);
|
|
410
|
+
pageLoadCallbacks.set(navCtx, loadResolve);
|
|
411
|
+
await Promise.race([loadPromise, new Promise(function(r) { setTimeout(r, 5000) })]);
|
|
412
|
+
pageLoadCallbacks.delete(navSid);
|
|
413
|
+
pageLoadCallbacks.delete(navCtx);
|
|
347
414
|
result = { navigation: nav.loaderId || null, url: params.url };
|
|
348
415
|
break;
|
|
349
416
|
}
|
|
@@ -356,6 +423,8 @@ async function handleBiDi(msg) {
|
|
|
356
423
|
pageSessions[tid] = { targetId: tid, sessionId: att.sessionId };
|
|
357
424
|
await cdpSend('Page.enable', {}, att.sessionId).catch(() => {});
|
|
358
425
|
await cdpSend('Runtime.enable', {}, att.sessionId).catch(() => {});
|
|
426
|
+
await cdpSend('Network.enable', {}, att.sessionId).catch(() => {});
|
|
427
|
+
for (var ps of pendingPreloadScripts) { try { await cdpSend('Page.addScriptToEvaluateOnNewDocument', { source: ps }, att.sessionId); } catch(e) {} }
|
|
359
428
|
result = { context: tid };
|
|
360
429
|
break;
|
|
361
430
|
}
|
|
@@ -374,17 +443,17 @@ async function handleBiDi(msg) {
|
|
|
374
443
|
case 'script.evaluate': {
|
|
375
444
|
const ctx = params.context || params.target?.context || mainContextId;
|
|
376
445
|
const sid = getSession(ctx);
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (
|
|
385
|
-
else if (
|
|
386
|
-
else
|
|
387
|
-
result = { realm: ctx, result:
|
|
446
|
+
let evalExpr = params.expression || '';
|
|
447
|
+
let evalWrapped = evalExpr.includes('=>') || evalExpr.startsWith('function') ? '(' + evalExpr + ')()' : '(function(){try{return (' + evalExpr + ')}catch(e){return {__error:e.message}}})()';
|
|
448
|
+
const evalR = await cdpSend('Runtime.evaluate', { expression: evalWrapped, awaitPromise: params.awaitPromise !== false, returnByValue: true }, sid);
|
|
449
|
+
if (evalR.exceptionDetails) throw { error: 'script error', message: evalR.exceptionDetails.text || 'eval error' };
|
|
450
|
+
const evalCr = evalR.result || {};
|
|
451
|
+
let evalBv;
|
|
452
|
+
if (evalCr.type === 'undefined' || evalCr.value === undefined) evalBv = { type: 'undefined' };
|
|
453
|
+
else if (evalCr.value === null) evalBv = { type: 'null' };
|
|
454
|
+
else if (evalCr.value && evalCr.value.__error) throw { error: 'script error', message: evalCr.value.__error };
|
|
455
|
+
else evalBv = { type: evalCr.type, value: evalCr.value };
|
|
456
|
+
result = { realm: ctx, result: evalBv };
|
|
388
457
|
break;
|
|
389
458
|
}
|
|
390
459
|
|
|
@@ -432,29 +501,29 @@ async function handleBiDi(msg) {
|
|
|
432
501
|
console.log('[bridge] CDP screenshot failed, trying hdc fallback...');
|
|
433
502
|
}
|
|
434
503
|
|
|
435
|
-
// Strategy 2:
|
|
504
|
+
// Strategy 2: snapshot_display fallback (local system command)
|
|
436
505
|
if (!imageData) {
|
|
437
506
|
try {
|
|
438
507
|
const { execSync } = require('child_process');
|
|
439
508
|
const fs = require('fs');
|
|
440
|
-
const hdcPath = '/data/service/hnp/bin/hdc';
|
|
441
509
|
|
|
442
510
|
// Take screenshot - snapshot_display saves to /data/local/tmp/snapshot_<timestamp>.jpeg
|
|
443
|
-
const output = execSync(
|
|
511
|
+
const output = execSync('snapshot_display', { timeout: 10000, encoding: 'utf-8' });
|
|
444
512
|
// Parse stdout for filename
|
|
445
513
|
const match = output.match(/set filename to (.+\.jpeg)/);
|
|
446
514
|
if (!match) throw new Error('snapshot_display did not return filename');
|
|
447
515
|
const deviceFile = match[1];
|
|
448
516
|
|
|
449
|
-
//
|
|
517
|
+
// Copy screenshot from local filesystem
|
|
450
518
|
const localFile = '/storage/Users/currentUser/tmp/bridge_ss.jpeg';
|
|
451
|
-
|
|
519
|
+
fs.mkdirSync(require('path').dirname(localFile), { recursive: true });
|
|
520
|
+
fs.copyFileSync(deviceFile, localFile);
|
|
452
521
|
const buf = fs.readFileSync(localFile);
|
|
453
522
|
imageData = buf.toString('base64');
|
|
454
|
-
console.log('[bridge] Screenshot via
|
|
523
|
+
console.log('[bridge] Screenshot via snapshot_display:', buf.length, 'bytes');
|
|
455
524
|
} catch(e) {
|
|
456
|
-
console.error('[bridge]
|
|
457
|
-
throw { error: 'screenshot', message: 'Screenshot failed: CDP and
|
|
525
|
+
console.error('[bridge] snapshot_display screenshot failed:', e.message.substring(0, 80));
|
|
526
|
+
throw { error: 'screenshot', message: 'Screenshot failed: CDP and snapshot_display both failed' };
|
|
458
527
|
}
|
|
459
528
|
}
|
|
460
529
|
|
|
@@ -601,6 +670,126 @@ async function handleBiDi(msg) {
|
|
|
601
670
|
break;
|
|
602
671
|
}
|
|
603
672
|
|
|
673
|
+
|
|
674
|
+
// ── vibium:page.eval ──
|
|
675
|
+
case 'vibium:page.eval': {
|
|
676
|
+
var peCtx = params.context || mainContextId;
|
|
677
|
+
await ensureSession(peCtx);
|
|
678
|
+
var peSid = getSession(peCtx);
|
|
679
|
+
var peR = await cdpSend('Runtime.evaluate', { expression: params.expression || '', returnByValue: true, awaitPromise: false }, peSid);
|
|
680
|
+
if (peR.exceptionDetails) throw { error: 'eval error', message: peR.exceptionDetails.text || 'eval error' };
|
|
681
|
+
result = { value: peR.result ? peR.result.value : undefined };
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
684
|
+
case 'vibium:page.find': {
|
|
685
|
+
var pfCtx = params.context || mainContextId;
|
|
686
|
+
await ensureSession(pfCtx);
|
|
687
|
+
var pfSid = getSession(pfCtx);
|
|
688
|
+
var pfSel = params.selector || '';
|
|
689
|
+
var pfExpr = '(function(){var el=document.querySelector(' + JSON.stringify(pfSel) + ');if(!el)return null;var b=el.getBoundingClientRect();return{tag:el.tagName.toLowerCase(),text:(el.textContent||"").substring(0,1000),box:{x:b.x,y:b.y,width:b.width,height:b.height}}})()';
|
|
690
|
+
var pfR = await cdpSend('Runtime.evaluate', { expression: pfExpr, returnByValue: true, awaitPromise: false }, pfSid);
|
|
691
|
+
if (pfR.exceptionDetails) throw { error: 'not found', message: pfR.exceptionDetails.text || 'find error' };
|
|
692
|
+
if (!pfR.result || !pfR.result.value) throw { error: 'not found', message: 'timeout after 30000ms waiting for ' + pfSel };
|
|
693
|
+
result = pfR.result.value;
|
|
694
|
+
break;
|
|
695
|
+
}
|
|
696
|
+
case 'vibium:page.findAll': {
|
|
697
|
+
var paCtx = params.context || mainContextId;
|
|
698
|
+
await ensureSession(paCtx);
|
|
699
|
+
var paSid = getSession(paCtx);
|
|
700
|
+
var paSel = params.selector || '';
|
|
701
|
+
var paExpr = '(function(){var els=document.querySelectorAll(' + JSON.stringify(paSel) + ');var arr=[];for(var i=0;i<els.length;i++){var b=els[i].getBoundingClientRect();arr.push({tag:els[i].tagName.toLowerCase(),text:(els[i].textContent||"").substring(0,1000),box:{x:b.x,y:b.y,width:b.width,height:b.height},index:i})}return{elements:arr}})()';
|
|
702
|
+
var paR = await cdpSend('Runtime.evaluate', { expression: paExpr, returnByValue: true }, paSid);
|
|
703
|
+
result = paR.result ? paR.result.value : { elements: [] };
|
|
704
|
+
break;
|
|
705
|
+
}
|
|
706
|
+
case 'vibium:page.title': { var tSid = getSession(params.context || mainContextId); var tR = await cdpSend('Runtime.evaluate', { expression: 'document.title', returnByValue: true }, tSid); result = { title: tR.result ? tR.result.value : '' }; break; }
|
|
707
|
+
case 'vibium:page.url': { var uSid = getSession(params.context || mainContextId); var uR = await cdpSend('Runtime.evaluate', { expression: 'location.href', returnByValue: true }, uSid); result = { url: uR.result ? uR.result.value : '' }; break; }
|
|
708
|
+
case 'vibium:page.content': { var cSid = getSession(params.context || mainContextId); var cR = await cdpSend('Runtime.evaluate', { expression: 'document.documentElement.outerHTML', returnByValue: true }, cSid); result = { content: cR.result ? cR.result.value : '' }; break; }
|
|
709
|
+
case 'vibium:page.screenshot': { var ssCtx = params.context || mainContextId; var ssSid = getSession(ssCtx); var ssR = await cdpSend('Page.captureScreenshot', { format: 'png' }, ssSid).catch(function(){return{}}); result = { data: ssR.data || '' }; break; }
|
|
710
|
+
case 'vibium:page.reload': { var rSid = getSession(params.context || mainContextId); await cdpSend('Page.reload', {}, rSid).catch(function(){}); result = {}; break; }
|
|
711
|
+
case 'vibium:page.navigate': { var ngCtx = params.context || mainContextId; var ngSid = getSession(ngCtx); await cdpSend('Page.navigate', { url: params.url }, ngSid); var ngR; var ngResolve; var ngP = new Promise(function(r){ngResolve=r}); pageLoadCallbacks.set(ngSid, ngResolve); pageLoadCallbacks.set(ngCtx, ngResolve); await Promise.race([ngP, new Promise(function(r){setTimeout(r,5000)})]); pageLoadCallbacks.delete(ngSid); pageLoadCallbacks.delete(ngCtx); result = { url: params.url }; break; }
|
|
712
|
+
case 'vibium:page.waitForLoad': { result = {}; break; }
|
|
713
|
+
case 'vibium:page.waitForURL': { var wuCtx = params.context || mainContextId; var wuSid = getSession(wuCtx); var wuUrl = params.url || ''; var wuR = await cdpSend('Runtime.evaluate', { expression: 'location.href', returnByValue: true }, wuSid); if ((wuR.result && wuR.result.value || '').indexOf(wuUrl) >= 0) { result = {}; } else { result = { error: 'timeout', message: 'waitForURL timeout: ' + wuUrl }; } break; }
|
|
714
|
+
case 'vibium:page.waitForFunction': { var wfCtx = params.context || mainContextId; var wfSid = getSession(wfCtx); var wfFn = params.fn || params.function || '() => true'; var wfExpr = wfFn.includes('=>') || wfFn.startsWith('function') ? '(' + wfFn + ')()' : wfFn; var wfTimeout = params.timeout || 30000; var wfStart = Date.now(); var wfVal = false; while (Date.now() - wfStart < wfTimeout) { try { var wfR = await cdpSend('Runtime.evaluate', { expression: wfExpr, returnByValue: true }, wfSid); if (wfR.result && wfR.result.value) { wfVal = true; break; } } catch(e) {} await new Promise(function(r){setTimeout(r,200)}); } result = { value: wfVal }; break; }
|
|
715
|
+
case 'vibium:page.emulateMedia': { var emSid = getSession(params.context || mainContextId); var emMm = {}; if (params.colorScheme) emMm['prefers-color-scheme'] = params.colorScheme; if (params.media) emMm['media'] = params.media; if (params.reducedMotion) emMm['prefers-reduced-motion'] = params.reducedMotion; if (Object.keys(emMm).length > 0) { var emStr = JSON.stringify(emMm); var emExpr = 'window.__mm=' + emStr + ';if(!window.__mmOrig)window.__mmOrig=window.matchMedia.bind(window);window.matchMedia=function(q){var r=window.__mmOrig(q);for(var k in window.__mm){if(q.indexOf(k)>=0){var m=Object.create(r);m.matches=q.indexOf(window.__mm[k])>=0;return m;}}return r;};'; await cdpSend('Runtime.evaluate', { expression: emExpr, returnByValue: true }, emSid).catch(function(){}); } result = {}; break; }
|
|
716
|
+
case 'vibium:page.setContent': { var scSid = getSession(params.context || mainContextId); await cdpSend('Runtime.evaluate', { expression: 'document.open();document.write(' + JSON.stringify(params.content || '') + ');document.close()', returnByValue: true }, scSid); result = {}; break; }
|
|
717
|
+
case 'vibium:page.frames': { var frSid = getSession(params.context || mainContextId); var frR = await cdpSend('Page.getFrameTree', {}, frSid); var frFrames = []; function frWalk(ft) { frFrames.push({url: ft.frame.url, name: ft.frame.name || '', context: ctx}); if (ft.childFrames) for (var c of ft.childFrames) frWalk(c); } if (frR.frameTree) frWalk(frR.frameTree); result = { frames: frFrames }; break; }
|
|
718
|
+
case 'vibium:page.frame': { var fmSid = getSession(params.context || mainContextId); var fmR = await cdpSend('Page.getFrameTree', {}, fmSid); var fmFound = null; function fmFind(ft, p) { if (p(ft.frame)) return ft.frame; if (ft.childFrames) for (var c of ft.childFrames) { var f = fmFind(c, p); if (f) return f; } return null; } if (fmR.frameTree) fmFound = fmFind(fmR.frameTree, function(f) { return (params.url && f.url.indexOf(params.url) >= 0) || (params.name && f.name === params.name); }); result = fmFound ? { url: fmFound.url, name: fmFound.name || '', context: ctx } : null; break; }
|
|
719
|
+
case 'vibium:page.a11yTree': { var aSid = getSession(params.context || mainContextId); var aExpr = '(function(){function gr(el){var r=el.getAttribute("role");if(r)return r;var m={a:"link",button:"button",h1:"heading",h2:"heading",h3:"heading",h4:"heading",h5:"heading",h6:"heading",img:"image",input:"textbox",nav:"navigation",main:"main",ul:"list",ol:"list",li:"listitem",select:"combobox",textarea:"textbox",form:"form",section:"region",article:"article",header:"banner",footer:"contentinfo"};return m[el.tagName.toLowerCase()]||"generic"}function gl(el){var a=el.getAttribute("aria-label");if(a)return a;var l=el.getAttribute("aria-labelledby");if(l){var t=document.getElementById(l);if(t)return t.textContent.trim()}var lbl=document.querySelector("label[for="+JSON.stringify(el.id)+"]");if(lbl)return lbl.textContent.trim();return el.textContent.trim().substring(0,100)}function w(el){var n={role:gr(el),name:gl(el)};if(el.tagName==="INPUT"&&el.type==="checkbox")n.checked=el.checked;if(el.tagName==="BUTTON"||el.tagName==="INPUT")n.disabled=el.disabled;if(el.tagName.match(/H[1-6]/))n.level=parseInt(el.tagName[1]);var ch=[];for(var i=0;i<el.children.length;i++)ch.push(w(el.children[i]));if(ch.length)n.children=ch;return n}return w(document.body)})()'; var aR = await cdpSend('Runtime.evaluate', { expression: aExpr, returnByValue: true }, aSid); result = aR.result && aR.result.value ? aR.result.value : { role: 'WebArea', name: '' }; break; }
|
|
720
|
+
case 'vibium:page.setViewport': { result = {}; break; }
|
|
721
|
+
case 'vibium:page.setWindow': { result = {}; break; }
|
|
722
|
+
case 'vibium:page.window': { result = { width: 1280, height: 720, x: 0, y: 0 }; break; }
|
|
723
|
+
case 'vibium:page.setGeolocation': { result = {}; break; }
|
|
724
|
+
case 'vibium:page.handleDialog': { var hdSid = getSession(params.context || mainContextId); await cdpSend('Page.handleJavaScriptDialog', { accept: params.accept !== false, promptText: params.promptText || '' }, hdSid).catch(function(){}); result = {}; break; }
|
|
725
|
+
case 'vibium:page.route': { result = {}; break; }
|
|
726
|
+
case 'vibium:page.unroute': { result = {}; break; }
|
|
727
|
+
case 'vibium:page.onWebSocket': { result = {}; break; }
|
|
728
|
+
case 'vibium:page.onConsole': { result = {}; break; }
|
|
729
|
+
case 'vibium:page.onError': { result = {}; break; }
|
|
730
|
+
case 'vibium:page.consoleMessages': { result = { messages: [] }; break; }
|
|
731
|
+
case 'vibium:page.errors': { result = { errors: [] }; break; }
|
|
732
|
+
case 'vibium:element.text': { var eSid = getSession(params.context || mainContextId); var eSel = params.selector || ''; var eIdx = params.index || 0; var eR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(eSel) + ')[' + eIdx + ']?.textContent||"")', returnByValue: true }, eSid); result = { text: eR.result ? eR.result.value : '' }; break; }
|
|
733
|
+
case 'vibium:element.innerText': { var eiSid = getSession(params.context || mainContextId); var eiSel = params.selector || ''; var eiIdx = params.index || 0; var eiR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(eiSel) + ')[' + eiIdx + ']?.innerText||"")', returnByValue: true }, eiSid); result = { text: eiR.result ? eiR.result.value : '' }; break; }
|
|
734
|
+
case 'vibium:element.html': { var ehSid = getSession(params.context || mainContextId); var ehSel = params.selector || ''; var ehIdx = params.index || 0; var ehR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(ehSel) + ')[' + ehIdx + ']?.innerHTML||"")', returnByValue: true }, ehSid); result = { html: ehR.result ? ehR.result.value : '' }; break; }
|
|
735
|
+
case 'vibium:element.value': { var evSid = getSession(params.context || mainContextId); var evSel = params.selector || ''; var evIdx = params.index || 0; var evR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(evSel) + ')[' + evIdx + ']?.value||"")', returnByValue: true }, evSid); result = { value: evR.result ? evR.result.value : '' }; break; }
|
|
736
|
+
case 'vibium:element.attr': { var atSid = getSession(params.context || mainContextId); var atSel = params.selector || ''; var atIdx = params.index || 0; var atName = params.name || ''; var atR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(atSel) + ')[' + atIdx + ']?.getAttribute(' + JSON.stringify(atName) + ')||null)', returnByValue: true }, atSid); result = { value: atR.result ? atR.result.value : null }; break; }
|
|
737
|
+
case 'vibium:element.bounds': { var bdSid = getSession(params.context || mainContextId); var bdSel = params.selector || ''; var bdIdx = params.index || 0; var bdR = await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(bdSel) + ')[' + bdIdx + '];if(!el)return{};var b=el.getBoundingClientRect();return{x:b.x,y:b.y,width:b.width,height:b.height}})()', returnByValue: true }, bdSid); result = bdR.result ? bdR.result.value : {}; break; }
|
|
738
|
+
case 'vibium:element.click': { var clSid = getSession(params.context || mainContextId); var clSel = params.selector || ''; var clIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(clSel) + ')[' + clIdx + ']?.click(),true)', returnByValue: true }, clSid); result = {}; break; }
|
|
739
|
+
case 'vibium:element.dblclick': { var dcSid = getSession(params.context || mainContextId); var dcSel = params.selector || ''; var dcIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(dcSel) + ')[' + dcIdx + '];if(el){el.focus();if(el.select){el.select()}else{var r=document.createRange();r.selectNodeContents(el);var s=window.getSelection();s.removeAllRanges();s.addRange(r)}el.dispatchEvent(new MouseEvent("dblclick",{bubbles:true}))}})()', returnByValue: true }, dcSid); result = {}; break; }
|
|
740
|
+
case 'vibium:element.type': { var tpSid = getSession(params.context || mainContextId); var tpSel = params.selector || ''; var tpIdx = params.index || 0; var tpText = params.text || ''; var tpExpr = '(function(){var el=document.querySelectorAll(' + JSON.stringify(tpSel) + ')[' + tpIdx + '];if(el){el.focus();el.value=(el.value||"")+' + JSON.stringify(tpText) + ';el.dispatchEvent(new Event("input",{bubbles:true}));el.dispatchEvent(new Event("change",{bubbles:true}))}})()'; await cdpSend('Runtime.evaluate', { expression: tpExpr, returnByValue: true }, tpSid); result = {}; break; }
|
|
741
|
+
case 'vibium:element.fill': { var flSid = getSession(params.context || mainContextId); var flSel = params.selector || ''; var flIdx = params.index || 0; var flText = params.text || ''; var flExpr = '(function(){var el=document.querySelectorAll(' + JSON.stringify(flSel) + ')[' + flIdx + '];if(el){el.focus();el.value=' + JSON.stringify(flText) + ';el.dispatchEvent(new Event("input",{bubbles:true}));el.dispatchEvent(new Event("change",{bubbles:true}))}})()'; await cdpSend('Runtime.evaluate', { expression: flExpr, returnByValue: true }, flSid); result = {}; break; }
|
|
742
|
+
case 'vibium:element.clear': { var crSid = getSession(params.context || mainContextId); var crSel = params.selector || ''; var crIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(crSel) + ')[' + crIdx + '];if(el){el.value="";el.dispatchEvent(new Event("input",{bubbles:true}))}})()', returnByValue: true }, crSid); result = {}; break; }
|
|
743
|
+
case 'vibium:element.hover': { var hvSid = getSession(params.context || mainContextId); var hvSel = params.selector || ''; var hvIdx = params.index || 0; var hvR = await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(hvSel) + ')[' + hvIdx + '];if(el){var r=el.getBoundingClientRect();return{x:r.x+r.width/2,y:r.y+r.height/2}}return null})()', returnByValue: true }, hvSid); if (hvR.result && hvR.result.value) { var hvV = hvR.result.value; await cdpSend('Input.dispatchMouseEvent', { type: 'mouseMoved', x: hvV.x, y: hvV.y }, hvSid); } result = {}; break; }
|
|
744
|
+
case 'vibium:element.focus': { var fcSid = getSession(params.context || mainContextId); var fcSel = params.selector || ''; var fcIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(fcSel) + ')[' + fcIdx + ']?.focus(),true)', returnByValue: true }, fcSid); result = {}; break; }
|
|
745
|
+
case 'vibium:element.press': { var prSid = getSession(params.context || mainContextId); var prSel = params.selector || ''; var prIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(prSel) + ')[' + prIdx + ']?.focus(),true)', returnByValue: true }, prSid); var prKey = params.key || 'Enter'; await cdpSend('Input.dispatchKeyEvent', { type: 'keyDown', key: prKey }, prSid); await cdpSend('Input.dispatchKeyEvent', { type: 'keyUp', key: prKey }, prSid); if (prKey === 'Enter') { await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.activeElement;if(el){var f=el.closest("form");if(f){f.dispatchEvent(new Event("submit",{bubbles:true,cancelable:true}));f.submit()}}})()', returnByValue: true }, prSid).catch(function(){}); } result = {}; break; }
|
|
746
|
+
case 'vibium:element.selectOption': { var soSid = getSession(params.context || mainContextId); var soSel = params.selector || ''; var soIdx = params.index || 0; var soVal = params.value || ''; var soR = await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(soSel) + ')[' + soIdx + '];if(!el)return false;var opts=el.options;if(!opts)return false;for(var i=0;i<opts.length;i++){if(opts[i].textContent.trim()===' + JSON.stringify(soVal) + '||opts[i].value===' + JSON.stringify(soVal) + '){el.selectedIndex=i;el.dispatchEvent(new Event("change",{bubbles:true}));return true}}return false})()', returnByValue: true }, soSid); if (!soR.result || !soR.result.value) throw { error: 'not found', message: 'no option matching: ' + soVal }; result = {}; break; }
|
|
747
|
+
case 'vibium:element.dispatchEvent': { var dsSid = getSession(params.context || mainContextId); var dsSel = params.selector || ''; var dsIdx = params.index || 0; var dsType = params.type || 'Event'; await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(dsSel) + ')[' + dsIdx + '];if(el){el.dispatchEvent(new CustomEvent(' + JSON.stringify(dsType) + ',{bubbles:true,cancelable:true}))}})()', returnByValue: true }, dsSid); result = {}; break; }
|
|
748
|
+
case 'vibium:element.scrollIntoView': { var siSid = getSession(params.context || mainContextId); var siSel = params.selector || ''; var siIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(siSel) + ')[' + siIdx + ']?.scrollIntoView({block:"center"}),true)', returnByValue: true }, siSid); result = {}; break; }
|
|
749
|
+
case 'vibium:element.check': { var ckSid = getSession(params.context || mainContextId); var ckSel = params.selector || ''; var ckIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(ckSel) + ')[' + ckIdx + '];if(el){el.checked=true;el.dispatchEvent(new Event("change",{bubbles:true}))}})()', returnByValue: true }, ckSid); result = {}; break; }
|
|
750
|
+
case 'vibium:element.uncheck': { var ucSid = getSession(params.context || mainContextId); var ucSel = params.selector || ''; var ucIdx = params.index || 0; await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(ucSel) + ')[' + ucIdx + '];if(el){el.checked=false;el.dispatchEvent(new Event("change",{bubbles:true}))}})()', returnByValue: true }, ucSid); result = {}; break; }
|
|
751
|
+
case 'vibium:element.isVisible': { var ivSid = getSession(params.context || mainContextId); var ivSel = params.selector || ''; var ivIdx = params.index || 0; var ivR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(ivSel) + ')[' + ivIdx + ']?.offsetParent !== null)', returnByValue: true }, ivSid); result = { visible: ivR.result ? ivR.result.value : false }; break; }
|
|
752
|
+
case 'vibium:element.isHidden': { var ihSid = getSession(params.context || mainContextId); var ihSel = params.selector || ''; var ihIdx = params.index || 0; var ihR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(ihSel) + ')[' + ihIdx + ']?.offsetParent === null)', returnByValue: true }, ihSid); result = { hidden: ihR.result ? ihR.result.value : false }; break; }
|
|
753
|
+
case 'vibium:element.isEnabled': { var ieSid = getSession(params.context || mainContextId); var ieSel = params.selector || ''; var ieIdx = params.index || 0; var ieR = await cdpSend('Runtime.evaluate', { expression: '(!document.querySelectorAll(' + JSON.stringify(ieSel) + ')[' + ieIdx + ']?.disabled)', returnByValue: true }, ieSid); result = { enabled: ieR.result ? ieR.result.value : false }; break; }
|
|
754
|
+
case 'vibium:element.isChecked': { var icSid = getSession(params.context || mainContextId); var icSel = params.selector || ''; var icIdx = params.index || 0; var icR = await cdpSend('Runtime.evaluate', { expression: '(document.querySelectorAll(' + JSON.stringify(icSel) + ')[' + icIdx + ']?.checked||false)', returnByValue: true }, icSid); result = { checked: icR.result ? icR.result.value : false }; break; }
|
|
755
|
+
case 'vibium:element.isEditable': { var edSid = getSession(params.context || mainContextId); var edSel = params.selector || ''; var edIdx = params.index || 0; var edR = await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(edSel) + ')[' + edIdx + '];return el&&!el.disabled&&!el.readOnly})()', returnByValue: true }, edSid); result = { editable: edR.result ? edR.result.value : false }; break; }
|
|
756
|
+
case 'vibium:element.screenshot': { var esSid = getSession(params.context || mainContextId); var esR = await cdpSend('Page.captureScreenshot', { format: 'png' }, esSid).catch(function(){return{}}); result = { data: esR.data || '' }; break; }
|
|
757
|
+
case 'vibium:element.role': { var rlSid = getSession(params.context || mainContextId); var rlSel = params.selector || ''; var rlIdx = params.index || 0; var rlR = await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(rlSel) + ')[' + rlIdx + '];if(!el)return "generic";var r=el.getAttribute("role");if(r)return r;var m={a:"link",button:"button",h1:"heading",h2:"heading",h3:"heading",h4:"heading",h5:"heading",h6:"heading",img:"image",input:"textbox",nav:"navigation",main:"main",ul:"list",ol:"list",li:"listitem",select:"combobox",textarea:"textbox",form:"form",section:"region",article:"article",header:"banner",footer:"contentinfo"};return m[el.tagName.toLowerCase()]||"generic"})()', returnByValue: true }, rlSid); result = { role: rlR.result ? rlR.result.value : 'generic' }; break; }
|
|
758
|
+
case 'vibium:element.label': { var lbSid = getSession(params.context || mainContextId); var lbSel = params.selector || ''; var lbIdx = params.index || 0; var lbR = await cdpSend('Runtime.evaluate', { expression: '(function(){var el=document.querySelectorAll(' + JSON.stringify(lbSel) + ')[' + lbIdx + '];if(!el)return "";var a=el.getAttribute("aria-label");if(a)return a;var l=el.getAttribute("aria-labelledby");if(l){var t=document.getElementById(l);if(t)return t.textContent.trim()}var lbl=document.querySelector("label[for="+JSON.stringify(el.id)+"]");if(lbl)return lbl.textContent.trim();return el.textContent.trim().substring(0,100)})()', returnByValue: true }, lbSid); result = { label: lbR.result ? lbR.result.value : '' }; break; }
|
|
759
|
+
case 'vibium:element.find': { var efSid = getSession(params.context || mainContextId); var efSel = params.selector || ''; var efScope = params.scope || ''; var efScopeExpr = efScope ? 'document.querySelector(' + JSON.stringify(efScope) + ')' : 'document'; var efExpr = '(function(){var sc=' + efScopeExpr + ';if(!sc)return null;var el=sc.querySelector(' + JSON.stringify(efSel) + ');if(!el)return null;var b=el.getBoundingClientRect();return{tag:el.tagName.toLowerCase(),text:(el.textContent||"").substring(0,1000),box:{x:b.x,y:b.y,width:b.width,height:b.height}}})()'; var efR = await cdpSend('Runtime.evaluate', { expression: efExpr, returnByValue: true }, efSid); if (!efR.result || !efR.result.value) throw { error: 'not found', message: 'element not found: ' + efSel }; result = efR.result.value; break; }
|
|
760
|
+
case 'vibium:element.findAll': { var eaSid = getSession(params.context || mainContextId); var eaSel = params.selector || ''; var eaScope = params.scope || ''; var eaScopeExpr = eaScope ? 'document.querySelector(' + JSON.stringify(eaScope) + ')' : 'document'; var eaExpr = '(function(){var sc=' + eaScopeExpr + ';if(!sc)return{elements:[]};var els=sc.querySelectorAll(' + JSON.stringify(eaSel) + ');var arr=[];for(var i=0;i<els.length;i++){var b=els[i].getBoundingClientRect();arr.push({tag:els[i].tagName.toLowerCase(),text:(els[i].textContent||"").substring(0,1000),box:{x:b.x,y:b.y,width:b.width,height:b.height},index:i})}return{elements:arr}})()'; var eaR = await cdpSend('Runtime.evaluate', { expression: eaExpr, returnByValue: true }, eaSid); result = eaR.result ? eaR.result.value : { elements: [] }; break; }
|
|
761
|
+
case 'vibium:keyboard.type': { var ktSid = getSession(params.context || mainContextId); await cdpSend('Runtime.evaluate', { expression: 'document.activeElement && (document.activeElement.value = (document.activeElement.value||"") + ' + JSON.stringify(params.text || '') + ')', returnByValue: true }, ktSid).catch(function(){}); result = {}; break; }
|
|
762
|
+
case 'vibium:keyboard.press': { var kpSid = getSession(params.context || mainContextId); var kpKey = params.key || 'Enter'; await cdpSend('Input.dispatchKeyEvent', { type: 'keyDown', key: kpKey }, kpSid); await cdpSend('Input.dispatchKeyEvent', { type: 'keyUp', key: kpKey }, kpSid); result = {}; break; }
|
|
763
|
+
case 'vibium:keyboard.down': { var kdSid = getSession(params.context || mainContextId); await cdpSend('Input.dispatchKeyEvent', { type: 'keyDown', key: params.key || 'Enter' }, kdSid); result = {}; break; }
|
|
764
|
+
case 'vibium:keyboard.up': { var kuSid = getSession(params.context || mainContextId); await cdpSend('Input.dispatchKeyEvent', { type: 'keyUp', key: params.key || 'Enter' }, kuSid); result = {}; break; }
|
|
765
|
+
case 'vibium:mouse.click': { var mcSid = getSession(params.context || mainContextId); await cdpSend('Input.dispatchMouseEvent', { type: 'mousePressed', x: params.x || 0, y: params.y || 0, button: 'left', clickCount: 1 }, mcSid); await cdpSend('Input.dispatchMouseEvent', { type: 'mouseReleased', x: params.x || 0, y: params.y || 0, button: 'left', clickCount: 1 }, mcSid); result = {}; break; }
|
|
766
|
+
case 'vibium:mouse.move': { var mmSid = getSession(params.context || mainContextId); await cdpSend('Input.dispatchMouseEvent', { type: 'mouseMoved', x: params.x || 0, y: params.y || 0 }, mmSid); result = {}; break; }
|
|
767
|
+
case 'vibium:mouse.down': { var mdSid = getSession(params.context || mainContextId); await cdpSend('Input.dispatchMouseEvent', { type: 'mousePressed', x: 0, y: 0, button: 'left', clickCount: 1 }, mdSid); result = {}; break; }
|
|
768
|
+
case 'vibium:mouse.up': { var muSid = getSession(params.context || mainContextId); await cdpSend('Input.dispatchMouseEvent', { type: 'mouseReleased', x: 0, y: 0, button: 'left', clickCount: 1 }, muSid); result = {}; break; }
|
|
769
|
+
case 'vibium:mouse.wheel': { var mwSid = getSession(params.context || mainContextId); await cdpSend('Runtime.evaluate', { expression: 'window.scrollBy(0,' + (params.deltaY || 100) + ')', returnByValue: true }, mwSid); result = {}; break; }
|
|
770
|
+
case 'vibium:clock.install': { result = {}; break; }
|
|
771
|
+
case 'vibium:clock.resume': { result = {}; break; }
|
|
772
|
+
case 'vibium:clock.setTimezone': { result = {}; break; }
|
|
773
|
+
case 'vibium:recording.start': { result = {}; break; }
|
|
774
|
+
case 'vibium:recording.stop': { result = { data: '' }; break; }
|
|
775
|
+
case 'vibium:recording.startChunk': { result = {}; break; }
|
|
776
|
+
case 'vibium:recording.stopChunk': { result = { data: '' }; break; }
|
|
777
|
+
case 'vibium:recording.startGroup': { result = {}; break; }
|
|
778
|
+
case 'vibium:recording.stopGroup': { result = {}; break; }
|
|
779
|
+
case 'vibium:browser.page': { result = { context: mainContextId, userContext: 'default' }; break; }
|
|
780
|
+
case 'vibium:browser.newPage': { var bnCreate = await cdpSend('Target.createTarget', { url: 'about:blank' }); var bnTid = bnCreate.targetId; var bnAtt = await cdpSend('Target.attachToTarget', { targetId: bnTid, flatten: true }); pageSessions[bnTid] = { targetId: bnTid, sessionId: bnAtt.sessionId }; await cdpSend('Page.enable', {}, bnAtt.sessionId).catch(function(){}); await cdpSend('Runtime.enable', {}, bnAtt.sessionId).catch(function(){}); for (var bnPs of pendingPreloadScripts) { try { await cdpSend('Page.addScriptToEvaluateOnNewDocument', { source: bnPs }, bnAtt.sessionId); } catch(e) {} } result = { context: bnTid, userContext: 'default' }; break; }
|
|
781
|
+
case 'vibium:browser.pages': { var bpR = await cdpSend('Target.getTargets', {}); result = { pages: ((bpR.targetInfos || []).filter(function(t){return t.type==='page'}).map(function(t){return {context: t.targetId, userContext: 'default'}})) }; break; }
|
|
782
|
+
case 'vibium:browser.stop': { result = {}; break; }
|
|
783
|
+
case 'vibium:browser.closeContext': { var ccKeys = Object.keys(pageSessions).filter(function(k){return k !== mainContextId}); if (ccKeys.length > 0) { var ccLast = ccKeys[ccKeys.length - 1]; try { await cdpSend('Target.closeTarget', { targetId: ccLast }); } catch(e) {} delete pageSessions[ccLast]; } result = {}; break; }
|
|
784
|
+
case 'vibium:context.newPage': { var cnCreate = await cdpSend('Target.createTarget', { url: 'about:blank' }); var cnTid = cnCreate.targetId; var cnAtt = await cdpSend('Target.attachToTarget', { targetId: cnTid, flatten: true }); pageSessions[cnTid] = { targetId: cnTid, sessionId: cnAtt.sessionId }; await cdpSend('Page.enable', {}, cnAtt.sessionId).catch(function(){}); await cdpSend('Runtime.enable', {}, cnAtt.sessionId).catch(function(){}); for (var cnPs of pendingPreloadScripts) { try { await cdpSend('Page.addScriptToEvaluateOnNewDocument', { source: cnPs }, cnAtt.sessionId); } catch(e) {} } result = { context: cnTid, userContext: params.userContext || 'default' }; break; }
|
|
785
|
+
case 'storage.getCookies': { await discoverAllSessions(); var scCookies = []; var scSessions = [mainSessionId]; for (var scK in pageSessions) { scSessions.push(pageSessions[scK].sessionId); } for (var scI = 0; scI < scSessions.length; scI++) { var scS = scSessions[scI]; try { var scR = await cdpSend('Network.getCookies', { urls: params.urls || [] }, scS); if (scR.cookies) scCookies = scCookies.concat(scR.cookies.map(function(c){c.path=c.path||'/';return c;})); } catch(e) {} try { var scR2 = await cdpSend('Runtime.evaluate', { expression: 'document.cookie', returnByValue: true }, scS); if (scR2.result && scR2.result.value) { scCookies = scCookies.concat(scR2.result.value.split(';').map(function(c){var p=c.trim().split('=');return{name:p[0],value:p.slice(1).join('=')||'',path:'/'};}).filter(function(c){return c.name;})); } } catch(e) {} } var scSeen = {}; scCookies = scCookies.filter(function(c){if(scSeen[c.name])return false;scSeen[c.name]=true;return true;}); result = { cookies: scCookies }; break; }
|
|
786
|
+
case 'storage.setCookie': { await discoverAllSessions(); var stC = params.cookie || {}; if (!stC.domain && stC.url) { try { stC.domain = new URL(stC.url).hostname; } catch(e) {} } var stSessions = [mainSessionId]; for (var stK in pageSessions) { stSessions.push(pageSessions[stK].sessionId); } for (var stI = 0; stI < stSessions.length; stI++) { var stS = stSessions[stI]; try { var stP = { name: stC.name, value: stC.value, domain: stC.domain || '', path: stC.path || '/' }; if (stC.domain) stP.url = 'http://' + stC.domain + (stC.path || '/'); await cdpSend('Network.setCookie', stP, stS); } catch(e) {} try { await cdpSend('Runtime.evaluate', { expression: 'document.cookie = ' + JSON.stringify(stC.name + '=' + stC.value + '; path=' + (stC.path || '/')), returnByValue: true }, stS); } catch(e) {} } result = {}; break; }
|
|
787
|
+
case 'storage.deleteCookies': { await discoverAllSessions(); var dcSessions = [mainSessionId]; for (var dcK in pageSessions) { dcSessions.push(pageSessions[dcK].sessionId); } for (var dcI = 0; dcI < dcSessions.length; dcI++) { try { await cdpSend('Network.clearBrowserCookies', {}, dcSessions[dcI]); } catch(e) {} } result = {}; break; }
|
|
788
|
+
case 'storage.getStorage': { await discoverAllSessions(); var gsCookies = []; var gsOrigins = []; var gsSessions = [mainSessionId]; for (var gsK in pageSessions) { gsSessions.push(pageSessions[gsK].sessionId); } for (var gsI = 0; gsI < gsSessions.length; gsI++) { var gsS = gsSessions[gsI]; try { var gsR = await cdpSend('Network.getCookies', { urls: params.urls || [] }, gsS); if (gsR.cookies) gsCookies = gsCookies.concat(gsR.cookies.map(function(c){c.path=c.path||'/';c.domain=c.domain||'';return c;})); } catch(e) {} try { var gsR2 = await cdpSend('Runtime.evaluate', { expression: 'document.cookie', returnByValue: true }, gsS); if (gsR2.result && gsR2.result.value) { gsCookies = gsCookies.concat(gsR2.result.value.split(';').map(function(c){var p=c.trim().split('=');return{name:p[0],value:p.slice(1).join('=')||'',path:'/'};}).filter(function(c){return c.name;})); } } catch(e) {} try { var gsSt = await cdpSend('Runtime.evaluate', { expression: '(function(){var items=[];for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);items.push({name:k,value:localStorage.getItem(k)})}return{origin:location.origin,localStorage:items,sessionStorage:[]}})()', returnByValue: true }, gsS); if (gsSt.result && gsSt.result.value) gsOrigins.push(gsSt.result.value); } catch(e) {} } var gsSeen = {}; gsCookies = gsCookies.filter(function(c){if(gsSeen[c.name])return false;gsSeen[c.name]=true;return true;}); gsOrigins = gsOrigins.filter(function(o){return o.localStorage && o.localStorage.length > 0;}); result = { cookies: gsCookies, origins: gsOrigins }; break; }
|
|
789
|
+
case 'storage.setStorage': { await discoverAllSessions(); var ssState = params.state || {}; var ssSessions = [mainSessionId]; for (var ssK in pageSessions) { ssSessions.push(pageSessions[ssK].sessionId); } for (var ssI = 0; ssI < ssSessions.length; ssI++) { var ssS = ssSessions[ssI]; if (ssState.cookies) { for (var ssC of ssState.cookies) { try { var ssP = {name: ssC.name, value: ssC.value, domain: ssC.domain || '', path: ssC.path || '/'}; if (ssC.domain) ssP.url = 'http://' + ssC.domain + (ssC.path || '/'); await cdpSend('Network.setCookie', ssP, ssS); } catch(e) {} try { await cdpSend('Runtime.evaluate', { expression: 'document.cookie = ' + JSON.stringify(ssC.name + '=' + ssC.value + '; path=' + (ssC.path || '/')), returnByValue: true }, ssS); } catch(e) {} } } if (ssState.origins) { for (var ssO of ssState.origins) { if (ssO.localStorage) { for (var ssItem of ssO.localStorage) { try { await cdpSend('Runtime.evaluate', { expression: 'localStorage.setItem(' + JSON.stringify(ssItem.name) + ', ' + JSON.stringify(ssItem.value) + ')', returnByValue: true }, ssS); } catch(e) {} } } if (ssO.sessionStorage) { for (var ssItem of ssO.sessionStorage) { try { await cdpSend('Runtime.evaluate', { expression: 'sessionStorage.setItem(' + JSON.stringify(ssItem.name) + ', ' + JSON.stringify(ssItem.value) + ')', returnByValue: true }, ssS); } catch(e) {} } } } } } result = {}; break; }
|
|
790
|
+
case 'storage.clearStorage': { await discoverAllSessions(); var clSessions = [mainSessionId]; for (var clK in pageSessions) { clSessions.push(pageSessions[clK].sessionId); } for (var clI = 0; clI < clSessions.length; clI++) { try { await cdpSend('Network.clearBrowserCookies', {}, clSessions[clI]); } catch(e) {} try { await cdpSend('Runtime.evaluate', { expression: 'localStorage.clear();sessionStorage.clear()', returnByValue: true }, clSessions[clI]); } catch(e) {} } result = {}; break; }
|
|
791
|
+
case 'script.addPreloadScript': { await discoverAllSessions(); var apsScript = params.script || ''; pendingPreloadScripts.push(apsScript); var apsSessions = [mainSessionId]; for (var apsK in pageSessions) { apsSessions.push(pageSessions[apsK].sessionId); } for (var apsI = 0; apsI < apsSessions.length; apsI++) { try { await cdpSend('Page.addScriptToEvaluateOnNewDocument', { source: apsScript }, apsSessions[apsI]); } catch(e) {} } result = {}; break; }
|
|
792
|
+
|
|
604
793
|
default:
|
|
605
794
|
console.log(`[bridge] Unhandled: ${method} (returning empty success)`);
|
|
606
795
|
result = {};
|
|
@@ -618,7 +807,28 @@ async function handleBiDi(msg) {
|
|
|
618
807
|
// ─── Server ──────────────────────────────────────────
|
|
619
808
|
async function start() {
|
|
620
809
|
await initCDP();
|
|
621
|
-
|
|
810
|
+
// HTTP endpoint for monkey-patch bypass
|
|
811
|
+
const httpServer = http.createServer(function(req, res) {
|
|
812
|
+
if (req.method === 'POST' && req.url === '/cmd') {
|
|
813
|
+
var body = '';
|
|
814
|
+
req.on('data', function(c) { body += c; });
|
|
815
|
+
req.on('end', function() {
|
|
816
|
+
try {
|
|
817
|
+
var hMsg = JSON.parse(body);
|
|
818
|
+
hMsg.id = hMsg.id || Date.now();
|
|
819
|
+
handleBiDi(hMsg).then(function(resp) {
|
|
820
|
+
res.writeHead(200, {'Content-Type':'application/json'});
|
|
821
|
+
res.end(JSON.stringify(resp));
|
|
822
|
+
}).catch(function(e) {
|
|
823
|
+
res.writeHead(200, {'Content-Type':'application/json'});
|
|
824
|
+
res.end(JSON.stringify({ id: hMsg.id, error: { code: 'unknown', message: e.message || 'error' } }));
|
|
825
|
+
});
|
|
826
|
+
} catch(e) { res.writeHead(400); res.end('{}'); }
|
|
827
|
+
});
|
|
828
|
+
} else { res.writeHead(404); res.end(); }
|
|
829
|
+
});
|
|
830
|
+
httpServer.listen(9518);
|
|
831
|
+
const wss = new WebSocket.Server({ port: LISTEN_PORT });
|
|
622
832
|
wss.on('connection', (ws, req) => {
|
|
623
833
|
console.log(`[bridge] Client: ${req.url}`);
|
|
624
834
|
bidiWs = ws; // Store for event forwarding
|
package/dist/index.js
CHANGED
|
@@ -2421,7 +2421,7 @@ var browser = {
|
|
|
2421
2421
|
if (process.platform === "openharmony" && !process.env.VIBIUM_CONNECT_URL) {
|
|
2422
2422
|
process.env.VIBIUM_SKIP_BROWSER_DOWNLOAD = "1";
|
|
2423
2423
|
const vibiumHome = process.env.HOME || "/storage/Users/currentUser";
|
|
2424
|
-
const
|
|
2424
|
+
const aaPath = "/system/bin/cli_tool/executable/ohos-aa";
|
|
2425
2425
|
const bridgePath = require("path").join(__dirname, "bidi-bridge.js");
|
|
2426
2426
|
const cdpPort = options.cdpPort || 9333;
|
|
2427
2427
|
const bridgePort = options.bridgePort || 9517;
|
|
@@ -2432,9 +2432,9 @@ var browser = {
|
|
|
2432
2432
|
const { execFileSync, spawn } = require("child_process");
|
|
2433
2433
|
const fs = require("fs");
|
|
2434
2434
|
const http = require("http");
|
|
2435
|
-
execFileSync(
|
|
2435
|
+
execFileSync(aaPath, ["force-stop", browserPkg], { timeout: 1e4, stdio: "pipe" });
|
|
2436
2436
|
const cmdArgs = `--remote-debugging-port=${cdpPort} --remote-allow-origins=http://127.0.0.1:${cdpPort} --disable-extensions --no-first-run --no-default-browser-check --disable-popup-blocking --disable-dev-shm-usage --password-store=basic --use-mock-keychain --force-color-profile=srgb`;
|
|
2437
|
-
execFileSync(
|
|
2437
|
+
execFileSync(aaPath, ["start", "-b", browserPkg, "-a", browserAbility, "--ps", "cmdArgs", cmdArgs], { timeout: 1e4, stdio: "pipe" });
|
|
2438
2438
|
for (let i = 0; i < 15; i++) {
|
|
2439
2439
|
try {
|
|
2440
2440
|
await new Promise((resolve2, reject2) => {
|
|
@@ -2481,7 +2481,7 @@ var browser = {
|
|
|
2481
2481
|
});
|
|
2482
2482
|
} catch (err) {
|
|
2483
2483
|
if (process.platform === "openharmony" && err instanceof BrowserCrashedError) {
|
|
2484
|
-
throw new BrowserCrashedError(err.exitCode, (err.output || "") + "\n\n[HarmonyOS] Browser launch failed. To use the native browser:\n Ensure
|
|
2484
|
+
throw new BrowserCrashedError(err.exitCode, (err.output || "") + "\n\n[HarmonyOS] Browser launch failed. To use the native browser:\n Ensure ohos-aa is available and the browser is installed.\nTo use a remote browser:\n export VIBIUM_CONNECT_URL=ws://<remote-host>:9222/session");
|
|
2485
2485
|
}
|
|
2486
2486
|
throw err;
|
|
2487
2487
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -2364,7 +2364,7 @@ var browser = {
|
|
|
2364
2364
|
if (process.platform === "openharmony" && !process.env.VIBIUM_CONNECT_URL) {
|
|
2365
2365
|
process.env.VIBIUM_SKIP_BROWSER_DOWNLOAD = "1";
|
|
2366
2366
|
const vibiumHome = process.env.HOME || "/storage/Users/currentUser";
|
|
2367
|
-
const
|
|
2367
|
+
const aaPath = "/system/bin/cli_tool/executable/ohos-aa";
|
|
2368
2368
|
const bridgePath = require("path").join(__dirname, "bidi-bridge.js");
|
|
2369
2369
|
const cdpPort = options.cdpPort || 9333;
|
|
2370
2370
|
const bridgePort = options.bridgePort || 9517;
|
|
@@ -2375,9 +2375,9 @@ if (process.platform === "openharmony" && !process.env.VIBIUM_CONNECT_URL) {
|
|
|
2375
2375
|
const { execFileSync, spawn } = require("child_process");
|
|
2376
2376
|
const fs = require("fs");
|
|
2377
2377
|
const http = require("http");
|
|
2378
|
-
execFileSync(
|
|
2378
|
+
execFileSync(aaPath, ["force-stop", browserPkg], { timeout: 1e4, stdio: "pipe" });
|
|
2379
2379
|
const cmdArgs = `--remote-debugging-port=${cdpPort} --remote-allow-origins=http://127.0.0.1:${cdpPort} --disable-extensions --no-first-run --no-default-browser-check --disable-popup-blocking --disable-dev-shm-usage --password-store=basic --use-mock-keychain --force-color-profile=srgb`;
|
|
2380
|
-
execFileSync(
|
|
2380
|
+
execFileSync(aaPath, ["start", "-b", browserPkg, "-a", browserAbility, "--ps", "cmdArgs", cmdArgs], { timeout: 1e4, stdio: "pipe" });
|
|
2381
2381
|
for (let i = 0; i < 15; i++) {
|
|
2382
2382
|
try {
|
|
2383
2383
|
await new Promise((resolve2, reject2) => {
|
|
@@ -2424,7 +2424,7 @@ if (process.platform === "openharmony" && !process.env.VIBIUM_CONNECT_URL) {
|
|
|
2424
2424
|
});
|
|
2425
2425
|
} catch (err) {
|
|
2426
2426
|
if (process.platform === "openharmony" && err instanceof BrowserCrashedError) {
|
|
2427
|
-
throw new BrowserCrashedError(err.exitCode, (err.output || "") + "\n\n[HarmonyOS] Browser launch failed. To use the native browser:\n Ensure
|
|
2427
|
+
throw new BrowserCrashedError(err.exitCode, (err.output || "") + "\n\n[HarmonyOS] Browser launch failed. To use the native browser:\n Ensure ohos-aa is available and the browser is installed.\nTo use a remote browser:\n export VIBIUM_CONNECT_URL=ws://<remote-host>:9222/session");
|
|
2428
2428
|
}
|
|
2429
2429
|
throw err;
|
|
2430
2430
|
}
|
package/dist/worker.js
CHANGED
|
@@ -2370,7 +2370,7 @@ var browser = {
|
|
|
2370
2370
|
if (process.platform === "openharmony" && !process.env.VIBIUM_CONNECT_URL) {
|
|
2371
2371
|
process.env.VIBIUM_SKIP_BROWSER_DOWNLOAD = "1";
|
|
2372
2372
|
const vibiumHome = process.env.HOME || "/storage/Users/currentUser";
|
|
2373
|
-
const
|
|
2373
|
+
const aaPath = "/system/bin/cli_tool/executable/ohos-aa";
|
|
2374
2374
|
const bridgePath = require("path").join(__dirname, "bidi-bridge.js");
|
|
2375
2375
|
const cdpPort = options.cdpPort || 9333;
|
|
2376
2376
|
const bridgePort = options.bridgePort || 9517;
|
|
@@ -2381,9 +2381,9 @@ if (process.platform === "openharmony" && !process.env.VIBIUM_CONNECT_URL) {
|
|
|
2381
2381
|
const { execFileSync, spawn } = require("child_process");
|
|
2382
2382
|
const fs = require("fs");
|
|
2383
2383
|
const http = require("http");
|
|
2384
|
-
execFileSync(
|
|
2384
|
+
execFileSync(aaPath, ["force-stop", browserPkg], { timeout: 1e4, stdio: "pipe" });
|
|
2385
2385
|
const cmdArgs = `--remote-debugging-port=${cdpPort} --remote-allow-origins=http://127.0.0.1:${cdpPort} --disable-extensions --no-first-run --no-default-browser-check --disable-popup-blocking --disable-dev-shm-usage --password-store=basic --use-mock-keychain --force-color-profile=srgb`;
|
|
2386
|
-
execFileSync(
|
|
2386
|
+
execFileSync(aaPath, ["start", "-b", browserPkg, "-a", browserAbility, "--ps", "cmdArgs", cmdArgs], { timeout: 1e4, stdio: "pipe" });
|
|
2387
2387
|
for (let i = 0; i < 15; i++) {
|
|
2388
2388
|
try {
|
|
2389
2389
|
await new Promise((resolve2, reject2) => {
|
|
@@ -2430,7 +2430,7 @@ if (process.platform === "openharmony" && !process.env.VIBIUM_CONNECT_URL) {
|
|
|
2430
2430
|
});
|
|
2431
2431
|
} catch (err) {
|
|
2432
2432
|
if (process.platform === "openharmony" && err instanceof BrowserCrashedError) {
|
|
2433
|
-
throw new BrowserCrashedError(err.exitCode, (err.output || "") + "\n\n[HarmonyOS] Browser launch failed. To use the native browser:\n Ensure
|
|
2433
|
+
throw new BrowserCrashedError(err.exitCode, (err.output || "") + "\n\n[HarmonyOS] Browser launch failed. To use the native browser:\n Ensure ohos-aa is available and the browser is installed.\nTo use a remote browser:\n export VIBIUM_CONNECT_URL=ws://<remote-host>:9222/session");
|
|
2434
2434
|
}
|
|
2435
2435
|
throw err;
|
|
2436
2436
|
}
|
package/package.json
CHANGED
package/README.md
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# Vibium
|
|
2
|
-
|
|
3
|
-
Browser automation for AI agents and humans.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install vibium
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
This automatically downloads Chrome for Testing on first install.
|
|
12
|
-
|
|
13
|
-
## Quick Start
|
|
14
|
-
|
|
15
|
-
### Async API
|
|
16
|
-
|
|
17
|
-
```javascript
|
|
18
|
-
import { browser } from 'vibium'
|
|
19
|
-
import { writeFile } from 'fs/promises'
|
|
20
|
-
|
|
21
|
-
const bro = await browser.start()
|
|
22
|
-
const vibe = await bro.page()
|
|
23
|
-
await vibe.go('https://example.com')
|
|
24
|
-
|
|
25
|
-
const link = await vibe.find('a')
|
|
26
|
-
console.log(await link.text())
|
|
27
|
-
await link.click()
|
|
28
|
-
|
|
29
|
-
const screenshot = await vibe.screenshot()
|
|
30
|
-
await writeFile('screenshot.png', screenshot)
|
|
31
|
-
|
|
32
|
-
await bro.stop()
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Sync API
|
|
36
|
-
|
|
37
|
-
```javascript
|
|
38
|
-
const { browser } = require('vibium/sync')
|
|
39
|
-
const { writeFileSync } = require('fs')
|
|
40
|
-
|
|
41
|
-
const bro = browser.start()
|
|
42
|
-
const vibe = bro.page()
|
|
43
|
-
vibe.go('https://example.com')
|
|
44
|
-
|
|
45
|
-
const link = vibe.find('a')
|
|
46
|
-
console.log(link.text())
|
|
47
|
-
link.click()
|
|
48
|
-
|
|
49
|
-
const screenshot = vibe.screenshot()
|
|
50
|
-
writeFileSync('screenshot.png', screenshot)
|
|
51
|
-
|
|
52
|
-
bro.stop()
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Environment Variables
|
|
56
|
-
|
|
57
|
-
| Variable | Description |
|
|
58
|
-
|----------|-------------|
|
|
59
|
-
| `VIBIUM_SKIP_BROWSER_DOWNLOAD` | Set to `1` to skip Chrome download on install |
|
|
60
|
-
|
|
61
|
-
## Requirements
|
|
62
|
-
|
|
63
|
-
- Node.js 18+
|
|
64
|
-
|
|
65
|
-
## Links
|
|
66
|
-
|
|
67
|
-
- [GitHub / Documentation](https://github.com/VibiumDev/vibium)
|
|
68
|
-
- [Website](https://vibium.com)
|
|
69
|
-
|
|
70
|
-
## License
|
|
71
|
-
|
|
72
|
-
Apache-2.0
|