@jobshimo/browser-link 0.36.0 → 0.37.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.
Files changed (38) hide show
  1. package/dist/agent-instructions/content.js +14 -3
  2. package/dist/agent-instructions/content.js.map +1 -1
  3. package/dist/cdp/flow.d.ts +36 -3
  4. package/dist/cdp/flow.js +54 -19
  5. package/dist/cdp/flow.js.map +1 -1
  6. package/dist/cdp/inpage/builders.d.ts +103 -20
  7. package/dist/cdp/inpage/builders.js +199 -52
  8. package/dist/cdp/inpage/builders.js.map +1 -1
  9. package/dist/cdp/inpage/observer.d.ts +36 -7
  10. package/dist/cdp/inpage/observer.js +242 -16
  11. package/dist/cdp/inpage/observer.js.map +1 -1
  12. package/dist/cdp/transport.js +90 -9
  13. package/dist/cdp/transport.js.map +1 -1
  14. package/dist/extension/background.js +91 -13
  15. package/dist/extension/background.js.map +1 -1
  16. package/dist/extension/flow.d.ts +36 -3
  17. package/dist/extension/flow.js +54 -19
  18. package/dist/extension/flow.js.map +1 -1
  19. package/dist/extension/inpage/builders.d.ts +103 -20
  20. package/dist/extension/inpage/builders.js +199 -52
  21. package/dist/extension/inpage/builders.js.map +1 -1
  22. package/dist/extension/inpage/observer.d.ts +36 -7
  23. package/dist/extension/inpage/observer.js +242 -16
  24. package/dist/extension/inpage/observer.js.map +1 -1
  25. package/dist/extension/manifest.json +1 -1
  26. package/dist/map/queries.d.ts +2 -0
  27. package/dist/map/queries.js +23 -1
  28. package/dist/map/queries.js.map +1 -1
  29. package/dist/map/tools.js +26 -4
  30. package/dist/map/tools.js.map +1 -1
  31. package/dist/tools/browser-definitions.js +80 -18
  32. package/dist/tools/browser-definitions.js.map +1 -1
  33. package/dist/tools/browser-dispatch.d.ts +19 -26
  34. package/dist/tools/browser-dispatch.js +152 -14
  35. package/dist/tools/browser-dispatch.js.map +1 -1
  36. package/dist/tools/server-instructions.js +14 -3
  37. package/dist/tools/server-instructions.js.map +1 -1
  38. package/package.json +1 -1
@@ -14,7 +14,7 @@ import { OBSERVER_GLOBAL } from './observer.js';
14
14
  * injected verbatim into `buildSnapshotJs`, `buildFindJs` and `buildStateJs`.
15
15
  * The observer global is looked up ONCE per evaluation and used only when it
16
16
  * is present, not torn down, and exposes `refFor`:
17
- * - `refOf(el)` returns the observer's `e<N>` ref for `el`, or `null`;
17
+ * - `refOf(el)` returns the observer's `<doc_tag>:e<N>` ref for `el`, or `null`;
18
18
  * - `withDocId(result)` adds `doc_id` to `result` and returns it;
19
19
  * - `snapshotStore()` returns the observer when it keeps snapshot records
20
20
  * (`recordSnapshot` / `getSnapshot`, used by `snapshot({ since })`), else
@@ -54,6 +54,53 @@ export const PAGE_OBSERVER_JS = `
54
54
  return null;
55
55
  }
56
56
  `;
57
+ /**
58
+ * In-page action-target resolution (spec v4 §6.3), injected after
59
+ * `DEEP_QUERY_JS` and `PAGE_OBSERVER_JS` into the builders that take a
60
+ * `selector` or a `ref` (click, type, focus, element rect, `wait_for` by
61
+ * ref, `find` by ref):
62
+ * `resolveTarget(opts)` with a non-empty `opts.ref` asks the observer
63
+ * (`resolveRefDetailed`, which re-resolves a replaced node by its semantic
64
+ * key) and answers `{ ok: true, el, reresolved }`, `{ ok: false, reason:
65
+ * 'ref-stale', ref, doc_id }` or `{ ok: false, reason: 'observer-unavailable'
66
+ * }`; otherwise it resolves `opts.selector` exactly as the selector builders
67
+ * always did (`invalid-selector` checked against `document` first, then
68
+ * `deepQueryFirst`, `not-found`). Kept out of `PAGE_OBSERVER_JS` so the
69
+ * snapshot and state sources do not carry code they never call.
70
+ */
71
+ export const RESOLVE_TARGET_JS = `
72
+ function resolveTarget(opts) {
73
+ if (typeof opts.ref === 'string' && opts.ref.length > 0) {
74
+ if (!pageObserver || typeof pageObserver.resolveRefDetailed !== 'function') {
75
+ return { ok: false, reason: 'observer-unavailable' };
76
+ }
77
+ let found = null;
78
+ try {
79
+ found = pageObserver.resolveRefDetailed(opts.ref);
80
+ } catch (e) {
81
+ found = null;
82
+ }
83
+ if (!found || !found.el) return withDocId({ ok: false, reason: 'ref-stale', ref: opts.ref });
84
+ return { ok: true, el: found.el, reresolved: found.reresolved === true };
85
+ }
86
+ try {
87
+ document.querySelector(opts.selector);
88
+ } catch (e) {
89
+ return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
90
+ }
91
+ const el = deepQueryFirst(opts.selector);
92
+ if (!el) return { ok: false, reason: 'not-found' };
93
+ return { ok: true, el: el, reresolved: false };
94
+ }
95
+ `;
96
+ /** JSON for the `selector` / `ref` pair, embedded as data in the built
97
+ * source; `ref` is included only when given so a selector build keeps the
98
+ * same options object as before. */
99
+ function targetJson(opts) {
100
+ return typeof opts.ref === 'string' && opts.ref.length > 0
101
+ ? { selector: opts.selector, ref: opts.ref }
102
+ : { selector: opts.selector };
103
+ }
57
104
  export function buildSnapshotJs(opts = {}) {
58
105
  const optsJson = JSON.stringify({
59
106
  withinSelector: typeof opts.within_selector === 'string' ? opts.within_selector : null,
@@ -246,6 +293,16 @@ export function buildSnapshotJs(opts = {}) {
246
293
  })()
247
294
  `;
248
295
  }
296
+ /** Only the documented key fields reach the built source, as JSON data. */
297
+ function findKeyJson(key) {
298
+ return Array.isArray(key.path)
299
+ ? {
300
+ role: key.role,
301
+ name: key.name,
302
+ path: key.path.map((step) => ({ tag: step.tag, index: step.index })),
303
+ }
304
+ : { role: key.role, name: key.name };
305
+ }
249
306
  export function buildFindJs(opts) {
250
307
  const optsJson = JSON.stringify({
251
308
  text: opts.text,
@@ -253,13 +310,98 @@ export function buildFindJs(opts) {
253
310
  exact: opts.exact === true,
254
311
  candidateLimit: 5,
255
312
  nearMissLimit: 3,
313
+ ...(typeof opts.ref === 'string' && opts.ref.length > 0 ? { ref: opts.ref } : {}),
314
+ ...(opts.key ? { key: findKeyJson(opts.key) } : {}),
256
315
  });
257
316
  return `
258
317
  (() => {
259
318
  ${DEEP_QUERY_JS}
260
319
  ${DOM_HELPERS_JS}
261
320
  ${PAGE_OBSERVER_JS}
321
+ ${typeof opts.ref === 'string' && opts.ref.length > 0 ? RESOLVE_TARGET_JS : ''}
262
322
  const opts = ${optsJson};
323
+ function semanticKeyOf(el) {
324
+ if (!pageObserver || typeof pageObserver.semanticKeyFor !== 'function') return null;
325
+ try {
326
+ const key = pageObserver.semanticKeyFor(el);
327
+ return key && typeof key === 'object' ? key : null;
328
+ } catch (e) {
329
+ return null;
330
+ }
331
+ }
332
+ function singleMatch(el, ref, reresolved) {
333
+ const center = viewportCenterOf(el);
334
+ const selInfo = genSelectorInfo(el);
335
+ const result = { matched: true, selector: selInfo.selector };
336
+ if (ref) result.ref = ref;
337
+ result.coords = {
338
+ x: Math.round(center.x),
339
+ y: Math.round(center.y),
340
+ };
341
+ result.tag = el.tagName.toLowerCase();
342
+ result.text = shortText(el);
343
+ if (selInfo.ambiguous) result.ambiguous = true;
344
+ const frame = frameSelectorFor(el);
345
+ if (frame) result.frame = frame;
346
+ if (reresolved) result.reresolved = true;
347
+ const key = semanticKeyOf(el);
348
+ if (key) result.semantic_key = key;
349
+ return withDocId(result);
350
+ }
351
+ if (typeof opts.ref === 'string') {
352
+ const target = resolveTarget(opts);
353
+ if (!target.ok) {
354
+ const failure = { matched: false, reason: target.reason, ref: opts.ref };
355
+ return withDocId(failure);
356
+ }
357
+ return singleMatch(target.el, opts.ref, target.reresolved);
358
+ }
359
+ if (opts.key) {
360
+ if (!pageObserver || typeof pageObserver.semanticKeyFor !== 'function') {
361
+ return { matched: false, reason: 'observer-unavailable' };
362
+ }
363
+ const wanted = opts.key;
364
+ const candidates = [];
365
+ for (const el of deepQueryAll('*')) {
366
+ const key = semanticKeyOf(el);
367
+ if (key && key.role === wanted.role && key.name === wanted.name) {
368
+ candidates.push({ el: el, path: Array.isArray(key.path) ? key.path : [] });
369
+ }
370
+ }
371
+ const count = candidates.length;
372
+ const shared = 'key: ' + count + ' candidates share role and name; ';
373
+ let picked = null;
374
+ let error = count > 1 ? shared + 'pass path to disambiguate' : null;
375
+ if (!Array.isArray(wanted.path)) {
376
+ if (count === 1) picked = candidates[0].el;
377
+ } else {
378
+ // Same rule as the observer's re-resolution: identical tag path and
379
+ // exactly one such candidate; identical rows are refused, never guessed.
380
+ let sameTags = 0;
381
+ let only = null;
382
+ for (const c of candidates) {
383
+ if (c.path.length !== wanted.path.length) continue;
384
+ let same = true;
385
+ for (let i = 0; i < c.path.length && same; i++) {
386
+ if (c.path[i].tag !== wanted.path[i].tag) same = false;
387
+ }
388
+ if (!same) continue;
389
+ sameTags++;
390
+ only = c.el;
391
+ }
392
+ if (sameTags === 1) {
393
+ picked = only;
394
+ } else if (sameTags > 1) {
395
+ error = 'key: ' + sameTags + ' candidates share role, name and tag path';
396
+ } else if (count > 0) {
397
+ error = shared + 'none has the same tag path';
398
+ }
399
+ }
400
+ if (picked) return singleMatch(picked, refOf(picked), false);
401
+ const failure = { matched: false, reason: 'not-found' };
402
+ if (error) failure.error = error;
403
+ return withDocId(failure);
404
+ }
263
405
  const needle = opts.text.toLowerCase();
264
406
  const needleTokens = needle.split(/[^a-z0-9]+/).filter(Boolean);
265
407
  const ROLE_SELECTORS = {
@@ -378,37 +520,21 @@ export function buildFindJs(opts) {
378
520
  });
379
521
  }
380
522
  const el = matches[0];
381
- const center = viewportCenterOf(el);
382
- const selInfo = genSelectorInfo(el);
383
- const result = { matched: true, selector: selInfo.selector };
384
- const ref = refOf(el);
385
- if (ref) result.ref = ref;
386
- result.coords = {
387
- x: Math.round(center.x),
388
- y: Math.round(center.y),
389
- };
390
- result.tag = el.tagName.toLowerCase();
391
- result.text = shortText(el);
392
- if (selInfo.ambiguous) result.ambiguous = true;
393
- const frame = frameSelectorFor(el);
394
- if (frame) result.frame = frame;
395
- return withDocId(result);
523
+ return singleMatch(el, refOf(el), false);
396
524
  })()
397
525
  `;
398
526
  }
399
527
  export function buildClickResolveJs(opts) {
400
- const optsJson = JSON.stringify({ selector: opts.selector, force: opts.force });
528
+ const optsJson = JSON.stringify({ ...targetJson(opts), force: opts.force });
401
529
  return `
402
530
  (() => {
403
531
  ${DEEP_QUERY_JS}
532
+ ${PAGE_OBSERVER_JS}
533
+ ${RESOLVE_TARGET_JS}
404
534
  const opts = ${optsJson};
405
- try {
406
- document.querySelector(opts.selector);
407
- } catch (e) {
408
- return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
409
- }
410
- const el = deepQueryFirst(opts.selector);
411
- if (!el) return { ok: false, reason: 'not-found' };
535
+ const target = resolveTarget(opts);
536
+ if (!target.ok) return target;
537
+ const el = target.el;
412
538
  const chain = frameElementChain(el);
413
539
  for (const fe of chain) {
414
540
  if (fe.scrollIntoView) fe.scrollIntoView({ block: 'center', inline: 'center' });
@@ -423,41 +549,59 @@ export function buildClickResolveJs(opts) {
423
549
  const result = { ok: true, x: center.x, y: center.y, tag };
424
550
  const hit = occlusion.allowed ? occlusion.hit : occlusion.blocker;
425
551
  if (hit) result.hit_element = hit;
552
+ if (target.reresolved) result.reresolved = true;
426
553
  return result;
427
554
  })()
428
555
  `;
429
556
  }
430
557
  export function buildTypeResolveJs(opts) {
431
- const optsJson = JSON.stringify({ selector: opts.selector });
558
+ const optsJson = JSON.stringify(targetJson(opts));
432
559
  return `
433
560
  (() => {
434
561
  ${DEEP_QUERY_JS}
562
+ ${PAGE_OBSERVER_JS}
563
+ ${RESOLVE_TARGET_JS}
435
564
  const opts = ${optsJson};
436
- try {
437
- document.querySelector(opts.selector);
438
- } catch (e) {
439
- return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
440
- }
441
- const el = deepQueryFirst(opts.selector);
442
- if (!el) return { ok: false, reason: 'not-found' };
565
+ const target = resolveTarget(opts);
566
+ if (!target.ok) return target;
567
+ const el = target.el;
443
568
  el.focus();
444
569
  ${opts.clear ? "if ('value' in el) { el.value = ''; el.dispatchEvent(new Event('input', { bubbles: true })); }" : ''}
445
- return { ok: true };
570
+ return target.reresolved ? { ok: true, reresolved: true } : { ok: true };
446
571
  })()`;
447
572
  }
448
573
  export function buildFocusJs(opts) {
449
- const optsJson = JSON.stringify({ selector: opts.selector });
574
+ const optsJson = JSON.stringify(targetJson(opts));
450
575
  return `
451
576
  (() => {
452
577
  ${DEEP_QUERY_JS}
578
+ ${PAGE_OBSERVER_JS}
579
+ ${RESOLVE_TARGET_JS}
453
580
  const opts = ${optsJson};
454
- const el = deepQueryFirst(opts.selector);
455
- if (!el) return false;
456
- el.focus();
457
- return true;
581
+ const target = resolveTarget(opts);
582
+ const byRef = typeof opts.ref === 'string';
583
+ if (!target.ok) return byRef ? target : false;
584
+ target.el.focus();
585
+ if (!byRef) return true;
586
+ return target.reresolved ? { ok: true, reresolved: true } : { ok: true };
458
587
  })()`;
459
588
  }
460
- export function buildWaitForSelectorJs(selector, condition) {
589
+ export function buildWaitForSelectorJs(target, condition) {
590
+ if (typeof target !== 'string') {
591
+ const refOptsJson = JSON.stringify({ ref: target.ref, condition });
592
+ return `
593
+ (() => {
594
+ ${DEEP_QUERY_JS}
595
+ ${PAGE_OBSERVER_JS}
596
+ ${RESOLVE_TARGET_JS}
597
+ const opts = ${refOptsJson};
598
+ const target = resolveTarget(opts);
599
+ if (!target.ok && target.reason === 'observer-unavailable') return target;
600
+ const el = target.ok ? target.el : null;
601
+ ${WAIT_FOR_CONDITION_JS}
602
+ })()`;
603
+ }
604
+ const selector = target;
461
605
  const optsJson = JSON.stringify({ selector, condition });
462
606
  return `
463
607
  (() => {
@@ -465,7 +609,12 @@ export function buildWaitForSelectorJs(selector, condition) {
465
609
  const opts = ${optsJson};
466
610
  document.querySelector(opts.selector);
467
611
  const el = deepQueryFirst(opts.selector);
468
- if (opts.condition === 'attached') return Boolean(el);
612
+ ${WAIT_FOR_CONDITION_JS}
613
+ })()`;
614
+ }
615
+ /** The condition check shared by both `wait_for` probe targets; `el` is
616
+ * the resolved element or `null`. */
617
+ const WAIT_FOR_CONDITION_JS = `if (opts.condition === 'attached') return Boolean(el);
469
618
  if (opts.condition === 'detached') return !el;
470
619
  const wantHidden = opts.condition === 'hidden';
471
620
  if (!el) return wantHidden;
@@ -474,22 +623,18 @@ export function buildWaitForSelectorJs(selector, condition) {
474
623
  if (s.display === 'none' || s.visibility === 'hidden' || s.opacity === '0') return wantHidden;
475
624
  const r = el.getBoundingClientRect();
476
625
  const shown = r.width > 0 && r.height > 0;
477
- return wantHidden ? !shown : shown;
478
- })()`;
479
- }
626
+ return wantHidden ? !shown : shown;`;
480
627
  export function buildElementRectJs(opts) {
481
- const optsJson = JSON.stringify({ selector: opts.selector });
628
+ const optsJson = JSON.stringify(targetJson(opts));
482
629
  return `
483
630
  (() => {
484
631
  ${DEEP_QUERY_JS}
632
+ ${PAGE_OBSERVER_JS}
633
+ ${RESOLVE_TARGET_JS}
485
634
  const opts = ${optsJson};
486
- try {
487
- document.querySelector(opts.selector);
488
- } catch (e) {
489
- return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
490
- }
491
- const el = deepQueryFirst(opts.selector);
492
- if (!el) return { ok: false, reason: 'not-found' };
635
+ const target = resolveTarget(opts);
636
+ if (!target.ok) return target;
637
+ const el = target.el;
493
638
  const chain = frameElementChain(el);
494
639
  // behavior 'instant' overrides CSS scroll-behavior: smooth, which would
495
640
  // leave the rect below stale while the scroll is still animating.
@@ -514,13 +659,15 @@ export function buildElementRectJs(opts) {
514
659
  scrollX = top.scrollX || 0;
515
660
  scrollY = top.scrollY || 0;
516
661
  } catch (_) {}
517
- return {
662
+ const result = {
518
663
  ok: true,
519
664
  x: offsetX + rect.left + scrollX,
520
665
  y: offsetY + rect.top + scrollY,
521
666
  width: rect.width,
522
667
  height: rect.height,
523
668
  };
669
+ if (target.reresolved) result.reresolved = true;
670
+ return result;
524
671
  })()`;
525
672
  }
526
673
  export function buildDragProbeJs(opts) {
@@ -1 +1 @@
1
- {"version":3,"file":"builders.js","sourceRoot":"","sources":["../../src/inpage/builders.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builders.js","sourceRoot":"","sources":["../../src/inpage/builders.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@
22
22
  * `cdp/builders-parity.test.ts` checks the built output.
23
23
  */
24
24
  /** Bump whenever the in-page protocol (global shape, messages, methods) changes. */
25
- export declare const OBSERVER_VERSION = 2;
25
+ export declare const OBSERVER_VERSION = 3;
26
26
  /** Name of the `Runtime.addBinding` function the observer pushes messages through. */
27
27
  export declare const OBSERVER_BINDING = "__blPageObserverPush";
28
28
  /** Well-known global that holds the installed observer instance. */
@@ -44,10 +44,30 @@ export interface ObserverInstallOpts {
44
44
  * `{ ok: true, installed, version, doc_id, coverage }`.
45
45
  *
46
46
  * The instance also owns element identity (spec v4 §5.6): `refFor(el)` issues
47
- * `e<N>` (monotonic per document instance, from `e1`) the first time an
48
- * element is seen and reuses it while the node lives; `resolveRef(ref)`
49
- * returns the element while it is connected, else `null`. Refs are only valid
50
- * for the `doc_id` that issued them. Neither method throws. `nextSnapshotId()`
47
+ * `<doc_tag>:e<N>` (`doc_tag` = the first 6 characters of `doc_id`, N
48
+ * monotonic per document instance, from 1) the first time an element is seen
49
+ * and reuses it while the node lives; `resolveRef(ref)` returns the element
50
+ * while it is connected, else `null`. Refs are only valid for the document
51
+ * instance that issued them: a ref whose tag is not this instance's tag, or a
52
+ * bare `e<N>` with no tag, is `null` everywhere (resolve, re-resolve, key)
53
+ * without consulting the registries. Neither method throws.
54
+ *
55
+ * Secondary identity (spec v4 §5.6, decided by lab 10): `semanticKeyFor(el)`
56
+ * returns `{ role, name, path }` — role from the `role` attribute or a small
57
+ * implicit table, accessible-ish name (aria-label, aria-labelledby, associated
58
+ * label, text ≤ 80 chars, placeholder, title, button-like input value) and up
59
+ * to 8 `{ tag, index }` ancestor steps (1-based same-tag sibling index, a
60
+ * shadow boundary as `{ tag: '#shadow', index: 0 }`). `refFor` stores the key
61
+ * when it issues a ref. `resolveRefDetailed(ref)` returns `{ el, reresolved }`:
62
+ * the live node with `reresolved: false`, else the element with the same role,
63
+ * name and tag-only path when exactly one exists, rebinding the ref to it
64
+ * (`reresolved: true`); zero or several candidates give `null` (sibling
65
+ * indices are kept in the key as data but never pick among candidates). Candidates come from the document, every open shadow root reachable
66
+ * from it, and every root the `attachShadow` patch observed (closed ones
67
+ * included); closed roots attached before install are not reachable.
68
+ * `resolveRef(ref)` is `resolveRefDetailed(ref)?.el ?? null`. `keyForRef(ref)`
69
+ * returns a copy of the stored key or `null`. None of these throws.
70
+ * `nextSnapshotId()`
51
71
  * issues `<doc_id>:s<N>` (N monotonic per document instance, from 1) for each
52
72
  * `snapshot` result and returns `null` once the instance is torn down; the
53
73
  * `doc_id` prefix lets a stale id from another document be rejected.
@@ -76,10 +96,19 @@ export declare function buildObserverChangesJs(mark: number, docId?: string): st
76
96
  /**
77
97
  * Build the ref-resolve expression, for tests and debugging. Evaluates to
78
98
  * `{ ok: true, found: true, tag }` when `ref` names an element of the current
79
- * document that is still connected, `{ ok: true, found: false }` when it is
80
- * unknown or stale, or `{ ok: false, reason: 'observer-unavailable' }`.
99
+ * document that is still connected — plus `reresolved: true` when the node was
100
+ * gone and the ref was just rebound by its semantic key —
101
+ * `{ ok: true, found: false }` when it is unknown or stale, or
102
+ * `{ ok: false, reason: 'observer-unavailable' }`.
81
103
  */
82
104
  export declare function buildObserverRefResolveJs(ref: string): string;
105
+ /**
106
+ * Build the semantic-key read expression. Evaluates to `{ ok: true, key }`
107
+ * with the `{ role, name, path }` stored when `ref` was issued, `{ ok: true,
108
+ * key: null }` for a ref this document instance does not know, or
109
+ * `{ ok: false, reason: 'observer-unavailable' }`.
110
+ */
111
+ export declare function buildObserverSemanticKeyJs(ref: string): string;
83
112
  /**
84
113
  * Build the teardown expression: disconnects every observer, restores the
85
114
  * `attachShadow` and `history` patches when they are still the observer's,