@browserbasehq/stagehand 3.0.7-alpha-4d71162beb119635b69b17637564a2bbd0e373e7 → 3.0.7-alpha-c6328376f19a9778d435980a992855e2b3bc6806

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 (2) hide show
  1. package/dist/index.js +1270 -1132
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -179,7 +179,7 @@ var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")])
179
179
  var STAGEHAND_VERSION;
180
180
  var init_version = __esm({
181
181
  "lib/version.ts"() {
182
- STAGEHAND_VERSION = "3.0.7-alpha-4d71162beb119635b69b17637564a2bbd0e373e7";
182
+ STAGEHAND_VERSION = "3.0.7-alpha-c6328376f19a9778d435980a992855e2b3bc6806";
183
183
  }
184
184
  });
185
185
 
@@ -638,39 +638,6 @@ var init_executionContextRegistry = __esm({
638
638
  }
639
639
  });
640
640
 
641
- // lib/v3/dom/build/a11yScripts.generated.ts
642
- var a11yScriptBootstrap, a11yScriptSources, a11yScriptGlobalRefs;
643
- var init_a11yScripts_generated = __esm({
644
- "lib/v3/dom/build/a11yScripts.generated.ts"() {
645
- a11yScriptBootstrap = 'if (!globalThis.__stagehandA11yScripts) { var __stagehandA11yScriptsFactory=(()=>{var i=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var N=(o,t)=>{for(var n in t)i(o,n,{get:t[n],enumerable:!0})},h=(o,t,n,d)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of f(t))!p.call(o,u)&&u!==n&&i(o,u,{get:()=>t[u],enumerable:!(d=a(t,u))||d.enumerable});return o};var E=o=>h(i({},"__esModule",{value:!0}),o);var b={};N(b,{documentHasFocusStrict:()=>g,getBoundingRectLite:()=>w,getScrollOffsets:()=>y,nodeToAbsoluteXPath:()=>$,resolveDeepActiveElement:()=>T});function y(){try{let o=window.scrollX??window.pageXOffset??document.documentElement?.scrollLeft??0,t=window.scrollY??window.pageYOffset??document.documentElement?.scrollTop??0;return{sx:Number(o)||0,sy:Number(t)||0}}catch{return{sx:0,sy:0}}}function w(){try{let o=this.getBoundingClientRect();return{left:Number(o?.left??0)||0,top:Number(o?.top??0)||0}}catch{return{left:0,top:0}}}function T(){try{return(t=>{let n=t.activeElement??null;for(;n&&n.shadowRoot&&n.shadowRoot.activeElement;)n=n.shadowRoot.activeElement;return n??null})(document)}catch{return null}}function $(){return(t=>{try{let n=e=>{if(!e||!e.parentNode)return 1;let l=1,m=`${e.nodeType}:${(e.nodeName||"").toLowerCase()}`;for(let c=e.previousSibling;c;c=c.previousSibling)`${c.nodeType}:${(c.nodeName||"").toLowerCase()}`===m&&(l+=1);return l},d=e=>{if(!e||e.nodeType===Node.DOCUMENT_NODE)return"";if(e.nodeType===Node.DOCUMENT_FRAGMENT_NODE)return"//";if(e.nodeType===Node.TEXT_NODE)return`text()[${n(e)}]`;if(e.nodeType===Node.COMMENT_NODE)return`comment()[${n(e)}]`;let l=(e.nodeName||"").toLowerCase();return`${l.includes(":")?`*[name()=\'${l}\']`:l}[${n(e)}]`},u=[],s=t;for(;s;){if(s.nodeType===Node.DOCUMENT_FRAGMENT_NODE){u.push("//"),s=s.host??null;continue}let e=d(s);e&&u.push(e),s=s.parentNode}u.reverse();let r="";for(let e of u)e==="//"?r=r?r.endsWith("/")?`${r}/`:`${r}//`:"//":r=r?r.endsWith("/")?`${r}${e}`:`${r}/${e}`:`/${e}`;return r||"/"}catch{return"/"}})(this)}function g(){try{return document.hasFocus()===!0}catch{return!1}}return E(b);})();\n globalThis.__stagehandA11yScripts = __stagehandA11yScriptsFactory;\n}';
646
- a11yScriptSources = {
647
- "documentHasFocusStrict": "function h(){try{return document.hasFocus()===!0}catch{return!1}}",
648
- "getBoundingRectLite": "function f(){try{let r=this.getBoundingClientRect();return{left:Number(r?.left??0)||0,top:Number(r?.top??0)||0}}catch{return{left:0,top:0}}}",
649
- "getScrollOffsets": "function a(){try{let r=window.scrollX??window.pageXOffset??document.documentElement?.scrollLeft??0,s=window.scrollY??window.pageYOffset??document.documentElement?.scrollTop??0;return{sx:Number(r)||0,sy:Number(s)||0}}catch{return{sx:0,sy:0}}}",
650
- "nodeToAbsoluteXPath": 'function N(){return(s=>{try{let n=e=>{if(!e||!e.parentNode)return 1;let u=1,d=`${e.nodeType}:${(e.nodeName||"").toLowerCase()}`;for(let l=e.previousSibling;l;l=l.previousSibling)`${l.nodeType}:${(l.nodeName||"").toLowerCase()}`===d&&(u+=1);return u},i=e=>{if(!e||e.nodeType===Node.DOCUMENT_NODE)return"";if(e.nodeType===Node.DOCUMENT_FRAGMENT_NODE)return"//";if(e.nodeType===Node.TEXT_NODE)return`text()[${n(e)}]`;if(e.nodeType===Node.COMMENT_NODE)return`comment()[${n(e)}]`;let u=(e.nodeName||"").toLowerCase();return`${u.includes(":")?`*[name()=\'${u}\']`:u}[${n(e)}]`},c=[],o=s;for(;o;){if(o.nodeType===Node.DOCUMENT_FRAGMENT_NODE){c.push("//"),o=o.host??null;continue}let e=i(o);e&&c.push(e),o=o.parentNode}c.reverse();let t="";for(let e of c)e==="//"?t=t?t.endsWith("/")?`${t}/`:`${t}//`:"//":t=t?t.endsWith("/")?`${t}${e}`:`${t}/${e}`:`/${e}`;return t||"/"}catch{return"/"}})(this)}',
651
- "resolveDeepActiveElement": "function p(){try{return(s=>{let n=s.activeElement??null;for(;n&&n.shadowRoot&&n.shadowRoot.activeElement;)n=n.shadowRoot.activeElement;return n??null})(document)}catch{return null}}"
652
- };
653
- a11yScriptGlobalRefs = {
654
- "documentHasFocusStrict": "globalThis.__stagehandA11yScripts.documentHasFocusStrict",
655
- "getBoundingRectLite": "globalThis.__stagehandA11yScripts.getBoundingRectLite",
656
- "getScrollOffsets": "globalThis.__stagehandA11yScripts.getScrollOffsets",
657
- "nodeToAbsoluteXPath": "globalThis.__stagehandA11yScripts.nodeToAbsoluteXPath",
658
- "resolveDeepActiveElement": "globalThis.__stagehandA11yScripts.resolveDeepActiveElement"
659
- };
660
- }
661
- });
662
-
663
- // lib/v3/understudy/a11yInvocation.ts
664
- function buildA11yInvocation(name, args) {
665
- const invocation = `${a11yScriptGlobalRefs[name]}(${args.join(", ")})`;
666
- return `(() => { ${a11yScriptBootstrap}; return ${invocation}; })()`;
667
- }
668
- var init_a11yInvocation = __esm({
669
- "lib/v3/understudy/a11yInvocation.ts"() {
670
- init_a11yScripts_generated();
671
- }
672
- });
673
-
674
641
  // lib/v3/dom/build/locatorScripts.generated.ts
675
642
  var locatorScriptBootstrap, locatorScriptSources, locatorScriptGlobalRefs;
676
643
  var init_locatorScripts_generated = __esm({
@@ -738,252 +705,60 @@ var init_locatorInvocation = __esm({
738
705
  }
739
706
  });
740
707
 
741
- // lib/v3/understudy/a11y/snapshot.ts
742
- function resolveXpathForLocation(page, x2, y) {
708
+ // lib/v3/dom/build/a11yScripts.generated.ts
709
+ var a11yScriptBootstrap, a11yScriptSources, a11yScriptGlobalRefs;
710
+ var init_a11yScripts_generated = __esm({
711
+ "lib/v3/dom/build/a11yScripts.generated.ts"() {
712
+ a11yScriptBootstrap = 'if (!globalThis.__stagehandA11yScripts) { var __stagehandA11yScriptsFactory=(()=>{var i=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var N=(o,t)=>{for(var n in t)i(o,n,{get:t[n],enumerable:!0})},h=(o,t,n,d)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of f(t))!p.call(o,u)&&u!==n&&i(o,u,{get:()=>t[u],enumerable:!(d=a(t,u))||d.enumerable});return o};var E=o=>h(i({},"__esModule",{value:!0}),o);var b={};N(b,{documentHasFocusStrict:()=>g,getBoundingRectLite:()=>w,getScrollOffsets:()=>y,nodeToAbsoluteXPath:()=>$,resolveDeepActiveElement:()=>T});function y(){try{let o=window.scrollX??window.pageXOffset??document.documentElement?.scrollLeft??0,t=window.scrollY??window.pageYOffset??document.documentElement?.scrollTop??0;return{sx:Number(o)||0,sy:Number(t)||0}}catch{return{sx:0,sy:0}}}function w(){try{let o=this.getBoundingClientRect();return{left:Number(o?.left??0)||0,top:Number(o?.top??0)||0}}catch{return{left:0,top:0}}}function T(){try{return(t=>{let n=t.activeElement??null;for(;n&&n.shadowRoot&&n.shadowRoot.activeElement;)n=n.shadowRoot.activeElement;return n??null})(document)}catch{return null}}function $(){return(t=>{try{let n=e=>{if(!e||!e.parentNode)return 1;let l=1,m=`${e.nodeType}:${(e.nodeName||"").toLowerCase()}`;for(let c=e.previousSibling;c;c=c.previousSibling)`${c.nodeType}:${(c.nodeName||"").toLowerCase()}`===m&&(l+=1);return l},d=e=>{if(!e||e.nodeType===Node.DOCUMENT_NODE)return"";if(e.nodeType===Node.DOCUMENT_FRAGMENT_NODE)return"//";if(e.nodeType===Node.TEXT_NODE)return`text()[${n(e)}]`;if(e.nodeType===Node.COMMENT_NODE)return`comment()[${n(e)}]`;let l=(e.nodeName||"").toLowerCase();return`${l.includes(":")?`*[name()=\'${l}\']`:l}[${n(e)}]`},u=[],s=t;for(;s;){if(s.nodeType===Node.DOCUMENT_FRAGMENT_NODE){u.push("//"),s=s.host??null;continue}let e=d(s);e&&u.push(e),s=s.parentNode}u.reverse();let r="";for(let e of u)e==="//"?r=r?r.endsWith("/")?`${r}/`:`${r}//`:"//":r=r?r.endsWith("/")?`${r}${e}`:`${r}/${e}`:`/${e}`;return r||"/"}catch{return"/"}})(this)}function g(){try{return document.hasFocus()===!0}catch{return!1}}return E(b);})();\n globalThis.__stagehandA11yScripts = __stagehandA11yScriptsFactory;\n}';
713
+ a11yScriptSources = {
714
+ "documentHasFocusStrict": "function h(){try{return document.hasFocus()===!0}catch{return!1}}",
715
+ "getBoundingRectLite": "function f(){try{let r=this.getBoundingClientRect();return{left:Number(r?.left??0)||0,top:Number(r?.top??0)||0}}catch{return{left:0,top:0}}}",
716
+ "getScrollOffsets": "function a(){try{let r=window.scrollX??window.pageXOffset??document.documentElement?.scrollLeft??0,s=window.scrollY??window.pageYOffset??document.documentElement?.scrollTop??0;return{sx:Number(r)||0,sy:Number(s)||0}}catch{return{sx:0,sy:0}}}",
717
+ "nodeToAbsoluteXPath": 'function N(){return(s=>{try{let n=e=>{if(!e||!e.parentNode)return 1;let u=1,d=`${e.nodeType}:${(e.nodeName||"").toLowerCase()}`;for(let l=e.previousSibling;l;l=l.previousSibling)`${l.nodeType}:${(l.nodeName||"").toLowerCase()}`===d&&(u+=1);return u},i=e=>{if(!e||e.nodeType===Node.DOCUMENT_NODE)return"";if(e.nodeType===Node.DOCUMENT_FRAGMENT_NODE)return"//";if(e.nodeType===Node.TEXT_NODE)return`text()[${n(e)}]`;if(e.nodeType===Node.COMMENT_NODE)return`comment()[${n(e)}]`;let u=(e.nodeName||"").toLowerCase();return`${u.includes(":")?`*[name()=\'${u}\']`:u}[${n(e)}]`},c=[],o=s;for(;o;){if(o.nodeType===Node.DOCUMENT_FRAGMENT_NODE){c.push("//"),o=o.host??null;continue}let e=i(o);e&&c.push(e),o=o.parentNode}c.reverse();let t="";for(let e of c)e==="//"?t=t?t.endsWith("/")?`${t}/`:`${t}//`:"//":t=t?t.endsWith("/")?`${t}${e}`:`${t}/${e}`:`/${e}`;return t||"/"}catch{return"/"}})(this)}',
718
+ "resolveDeepActiveElement": "function p(){try{return(s=>{let n=s.activeElement??null;for(;n&&n.shadowRoot&&n.shadowRoot.activeElement;)n=n.shadowRoot.activeElement;return n??null})(document)}catch{return null}}"
719
+ };
720
+ a11yScriptGlobalRefs = {
721
+ "documentHasFocusStrict": "globalThis.__stagehandA11yScripts.documentHasFocusStrict",
722
+ "getBoundingRectLite": "globalThis.__stagehandA11yScripts.getBoundingRectLite",
723
+ "getScrollOffsets": "globalThis.__stagehandA11yScripts.getScrollOffsets",
724
+ "nodeToAbsoluteXPath": "globalThis.__stagehandA11yScripts.nodeToAbsoluteXPath",
725
+ "resolveDeepActiveElement": "globalThis.__stagehandA11yScripts.resolveDeepActiveElement"
726
+ };
727
+ }
728
+ });
729
+
730
+ // lib/v3/understudy/a11y/snapshot/xpathUtils.ts
731
+ function buildAbsoluteXPathFromChain(chain, leafSession, leafBackendNodeId) {
743
732
  return __async(this, null, function* () {
744
- var _a4, _b, _c, _d2, _e, _f, _g, _h;
745
- const tree = page.getFullFrameTree();
746
- const parentByFrame = /* @__PURE__ */ new Map();
747
- (function index(n, parent) {
748
- var _a5;
749
- parentByFrame.set(n.frame.id, parent);
750
- for (const c of (_a5 = n.childFrames) != null ? _a5 : []) index(c, n.frame.id);
751
- })(tree, null);
752
- const iframeChain = [];
753
- let curFrameId = page.mainFrameId();
754
- let curSession = page.getSessionForFrame(curFrameId);
755
- let curX = x2;
756
- let curY = y;
757
- for (let depth = 0; depth < 8; depth++) {
758
- try {
759
- yield curSession.send("DOM.enable").catch(() => {
760
- });
761
- let sx = 0;
762
- let sy = 0;
763
- try {
764
- yield curSession.send("Runtime.enable").catch(() => {
765
- });
766
- const ctxId = yield executionContexts.waitForMainWorld(curSession, curFrameId).catch(() => {
767
- });
768
- const scrollExpr = buildA11yInvocation("getScrollOffsets", []);
769
- const evalParams = ctxId ? {
770
- contextId: ctxId,
771
- expression: scrollExpr,
772
- returnByValue: true
773
- } : { expression: scrollExpr, returnByValue: true };
774
- const { result } = yield curSession.send("Runtime.evaluate", evalParams);
775
- sx = Number((_b = (_a4 = result == null ? void 0 : result.value) == null ? void 0 : _a4.sx) != null ? _b : 0);
776
- sy = Number((_d2 = (_c = result == null ? void 0 : result.value) == null ? void 0 : _c.sy) != null ? _d2 : 0);
777
- } catch (e2) {
778
- }
779
- const xi = Math.max(0, Math.floor(curX + sx));
780
- const yi = Math.max(0, Math.floor(curY + sy));
781
- let res;
782
- try {
783
- res = yield curSession.send("DOM.getNodeForLocation", {
784
- x: xi,
785
- y: yi,
786
- includeUserAgentShadowDOM: false,
787
- ignorePointerEventsNone: false
788
- });
789
- } catch (e2) {
790
- return null;
791
- }
792
- const be = res == null ? void 0 : res.backendNodeId;
793
- const reportedFrameId = res == null ? void 0 : res.frameId;
794
- if (typeof be === "number" && reportedFrameId && reportedFrameId !== curFrameId) {
795
- const abs = yield buildAbsoluteXPathFromChain(
796
- iframeChain,
797
- curSession,
798
- be
799
- );
800
- return abs ? { frameId: reportedFrameId, backendNodeId: be, absoluteXPath: abs } : null;
801
- }
802
- if (typeof be !== "number") return null;
803
- let matchedChild;
804
- for (const fid of listChildrenOf(parentByFrame, curFrameId)) {
805
- try {
806
- const { backendNodeId } = yield curSession.send("DOM.getFrameOwner", { frameId: fid });
807
- if (backendNodeId === be) {
808
- matchedChild = fid;
809
- break;
810
- }
811
- } catch (e2) {
812
- }
813
- }
814
- if (!matchedChild) {
815
- const abs = yield buildAbsoluteXPathFromChain(
816
- iframeChain,
817
- curSession,
818
- be
819
- );
820
- return abs ? { frameId: curFrameId, backendNodeId: be, absoluteXPath: abs } : null;
821
- }
822
- iframeChain.push({
823
- parentFrameId: curFrameId,
824
- parentSession: curSession,
825
- iframeBackendNodeId: be
826
- });
827
- let left = 0;
828
- let top = 0;
829
- try {
830
- const { object } = yield curSession.send("DOM.resolveNode", { backendNodeId: be });
831
- const objectId = object == null ? void 0 : object.objectId;
832
- if (objectId) {
833
- const { result } = yield curSession.send("Runtime.callFunctionOn", {
834
- objectId,
835
- functionDeclaration: a11yScriptSources.getBoundingRectLite,
836
- returnByValue: true
837
- });
838
- left = Number((_f = (_e = result == null ? void 0 : result.value) == null ? void 0 : _e.left) != null ? _f : 0);
839
- top = Number((_h = (_g = result == null ? void 0 : result.value) == null ? void 0 : _g.top) != null ? _h : 0);
840
- yield curSession.send("Runtime.releaseObject", { objectId }).catch(() => {
841
- });
842
- }
843
- } catch (e2) {
844
- }
845
- curX = Math.max(0, curX - left);
846
- curY = Math.max(0, curY - top);
847
- curFrameId = matchedChild;
848
- curSession = page.getSessionForFrame(curFrameId);
849
- } catch (e2) {
850
- return null;
851
- }
733
+ let prefix = "";
734
+ for (const step of chain) {
735
+ const xp = yield absoluteXPathForBackendNode(
736
+ step.parentSession,
737
+ step.iframeBackendNodeId
738
+ );
739
+ if (!xp) continue;
740
+ prefix = prefix ? prefixXPath(prefix, xp) : normalizeXPath(xp);
852
741
  }
853
- return null;
742
+ const leaf = yield absoluteXPathForBackendNode(
743
+ leafSession,
744
+ leafBackendNodeId
745
+ );
746
+ if (!leaf) return prefix || "/";
747
+ return prefix ? prefixXPath(prefix, leaf) : normalizeXPath(leaf);
854
748
  });
855
749
  }
856
- function computeActiveElementXpath(page) {
750
+ function absoluteXPathForBackendNode(session, backendNodeId) {
857
751
  return __async(this, null, function* () {
858
- var _a4;
859
- const tree = page.getFullFrameTree();
860
- const parentByFrame = /* @__PURE__ */ new Map();
861
- (function index(n, parent) {
862
- var _a5;
863
- parentByFrame.set(n.frame.id, parent);
864
- for (const c of (_a5 = n.childFrames) != null ? _a5 : []) index(c, n.frame.id);
865
- })(tree, null);
866
- const frames = page.listAllFrameIds();
867
- let focusedFrameId = null;
868
- for (const fid of frames) {
869
- const sess = page.getSessionForFrame(fid);
870
- try {
871
- yield sess.send("Runtime.enable").catch(() => {
872
- });
873
- const ctxId = yield executionContexts.waitForMainWorld(sess, fid, 1e3).catch(() => {
874
- });
875
- const hasFocusExpr = buildA11yInvocation("documentHasFocusStrict", []);
876
- const evalParams = ctxId ? {
877
- contextId: ctxId,
878
- expression: hasFocusExpr,
879
- returnByValue: true
880
- } : { expression: hasFocusExpr, returnByValue: true };
881
- const { result } = yield sess.send(
882
- "Runtime.evaluate",
883
- evalParams
884
- );
885
- if ((result == null ? void 0 : result.value) === true) {
886
- focusedFrameId = fid;
887
- break;
888
- }
889
- } catch (e2) {
890
- }
891
- }
892
- if (!focusedFrameId) focusedFrameId = page.mainFrameId();
893
- const focusedSession = page.getSessionForFrame(focusedFrameId);
894
- let objectId;
895
752
  try {
896
- yield focusedSession.send("Runtime.enable").catch(() => {
897
- });
898
- const ctxId = yield executionContexts.waitForMainWorld(focusedSession, focusedFrameId, 1e3).catch(() => {
899
- });
900
- const activeExpr = buildA11yInvocation("resolveDeepActiveElement", []);
901
- const evalParams = ctxId ? {
902
- contextId: ctxId,
903
- expression: activeExpr,
904
- returnByValue: false
905
- } : { expression: activeExpr, returnByValue: false };
906
- const { result } = yield focusedSession.send(
907
- "Runtime.evaluate",
908
- evalParams
753
+ const { object } = yield session.send(
754
+ "DOM.resolveNode",
755
+ { backendNodeId }
909
756
  );
910
- objectId = result == null ? void 0 : result.objectId;
911
- } catch (e2) {
912
- objectId = void 0;
913
- }
914
- if (!objectId) return null;
915
- const leafXPath = yield (() => __async(null, null, function* () {
916
- try {
917
- const { result } = yield focusedSession.send("Runtime.callFunctionOn", {
918
- objectId,
919
- functionDeclaration: a11yScriptSources.nodeToAbsoluteXPath,
920
- returnByValue: true
921
- });
922
- try {
923
- yield focusedSession.send("Runtime.releaseObject", { objectId });
924
- } catch (e2) {
925
- }
926
- const xp = (result == null ? void 0 : result.value) || "";
927
- return typeof xp === "string" && xp ? xp : null;
928
- } catch (e2) {
929
- try {
930
- yield focusedSession.send("Runtime.releaseObject", { objectId });
931
- } catch (e3) {
932
- }
933
- return null;
934
- }
935
- }))();
936
- if (!leafXPath) return null;
937
- let prefix = "";
938
- let cur = focusedFrameId;
939
- while (cur) {
940
- const parent = (_a4 = parentByFrame.get(cur)) != null ? _a4 : null;
941
- if (!parent) break;
942
- const parentSess = page.getSessionForFrame(parent);
943
- try {
944
- const { backendNodeId } = yield parentSess.send("DOM.getFrameOwner", { frameId: cur });
945
- if (typeof backendNodeId === "number") {
946
- const xp = yield absoluteXPathForBackendNode(parentSess, backendNodeId);
947
- if (xp) prefix = prefix ? prefixXPath(prefix, xp) : normalizeXPath(xp);
948
- }
949
- } catch (e2) {
950
- }
951
- cur = parent;
952
- }
953
- return prefix ? prefixXPath(prefix, leafXPath) : normalizeXPath(leafXPath);
954
- });
955
- }
956
- function buildAbsoluteXPathFromChain(chain, leafSession, leafBackendNodeId) {
957
- return __async(this, null, function* () {
958
- let prefix = "";
959
- for (const step of chain) {
960
- const xp = yield absoluteXPathForBackendNode(
961
- step.parentSession,
962
- step.iframeBackendNodeId
963
- );
964
- if (!xp) continue;
965
- prefix = prefix ? prefixXPath(prefix, xp) : normalizeXPath(xp);
966
- }
967
- const leaf = yield absoluteXPathForBackendNode(
968
- leafSession,
969
- leafBackendNodeId
970
- );
971
- if (!leaf) return prefix || "/";
972
- return prefix ? prefixXPath(prefix, leaf) : normalizeXPath(leaf);
973
- });
974
- }
975
- function absoluteXPathForBackendNode(session, backendNodeId) {
976
- return __async(this, null, function* () {
977
- try {
978
- const { object } = yield session.send(
979
- "DOM.resolveNode",
980
- { backendNodeId }
981
- );
982
- const objectId = object == null ? void 0 : object.objectId;
983
- if (!objectId) return null;
984
- const { result } = yield session.send(
985
- "Runtime.callFunctionOn",
986
- {
757
+ const objectId = object == null ? void 0 : object.objectId;
758
+ if (!objectId) return null;
759
+ const { result } = yield session.send(
760
+ "Runtime.callFunctionOn",
761
+ {
987
762
  objectId,
988
763
  functionDeclaration: a11yScriptSources.nodeToAbsoluteXPath,
989
764
  returnByValue: true
@@ -997,483 +772,168 @@ function absoluteXPathForBackendNode(session, backendNodeId) {
997
772
  }
998
773
  });
999
774
  }
1000
- function isCborStackError(message) {
1001
- return message.includes("CBOR: stack limit exceeded");
775
+ function prefixXPath(parentAbs, child) {
776
+ const p = parentAbs === "/" ? "" : parentAbs.replace(/\/$/, "");
777
+ if (!child || child === "/") return p || "/";
778
+ if (child.startsWith("//"))
779
+ return p ? `${p}//${child.slice(2)}` : `//${child.slice(2)}`;
780
+ const c = child.replace(/^\//, "");
781
+ return p ? `${p}/${c}` : `/${c}`;
1002
782
  }
1003
- function shouldExpandNode(node) {
1004
- var _a4, _b, _c;
1005
- const declaredChildren = (_a4 = node.childNodeCount) != null ? _a4 : 0;
1006
- const realizedChildren = (_c = (_b = node.children) == null ? void 0 : _b.length) != null ? _c : 0;
1007
- return declaredChildren > realizedChildren;
783
+ function normalizeXPath(x2) {
784
+ if (!x2) return "";
785
+ let s2 = x2.trim().replace(/^xpath=/i, "");
786
+ if (!s2.startsWith("/")) s2 = "/" + s2;
787
+ if (s2.length > 1 && s2.endsWith("/")) s2 = s2.slice(0, -1);
788
+ return s2;
1008
789
  }
1009
- function mergeDomNodes(target, source) {
1010
- var _a4, _b, _c, _d2;
1011
- target.childNodeCount = (_a4 = source.childNodeCount) != null ? _a4 : target.childNodeCount;
1012
- target.children = (_b = source.children) != null ? _b : target.children;
1013
- target.shadowRoots = (_c = source.shadowRoots) != null ? _c : target.shadowRoots;
1014
- target.contentDocument = (_d2 = source.contentDocument) != null ? _d2 : target.contentDocument;
790
+ function buildChildXPathSegments(kids) {
791
+ var _a4;
792
+ const segs = [];
793
+ const ctr = {};
794
+ for (const child of kids) {
795
+ const tag = String(child.nodeName).toLowerCase();
796
+ const key = `${child.nodeType}:${tag}`;
797
+ const idx = ctr[key] = ((_a4 = ctr[key]) != null ? _a4 : 0) + 1;
798
+ if (child.nodeType === 3) {
799
+ segs.push(`text()[${idx}]`);
800
+ } else if (child.nodeType === 8) {
801
+ segs.push(`comment()[${idx}]`);
802
+ } else {
803
+ segs.push(
804
+ tag.includes(":") ? `*[name()='${tag}'][${idx}]` : `${tag}[${idx}]`
805
+ );
806
+ }
807
+ }
808
+ return segs;
1015
809
  }
1016
- function collectDomTraversalTargets(node) {
1017
- const targets = [];
1018
- if (node.children) targets.push(...node.children);
1019
- if (node.shadowRoots) targets.push(...node.shadowRoots);
1020
- if (node.contentDocument) targets.push(node.contentDocument);
1021
- return targets;
810
+ function joinXPath(base, step) {
811
+ if (step === "//") {
812
+ if (!base || base === "/") return "//";
813
+ return base.endsWith("/") ? `${base}/` : `${base}//`;
814
+ }
815
+ if (!base || base === "/") return step ? `/${step}` : "/";
816
+ if (base.endsWith("//")) return `${base}${step}`;
817
+ if (!step) return base;
818
+ return `${base}/${step}`;
1022
819
  }
1023
- function hydrateDomTree(session, root, pierce) {
820
+ var init_xpathUtils = __esm({
821
+ "lib/v3/understudy/a11y/snapshot/xpathUtils.ts"() {
822
+ init_a11yScripts_generated();
823
+ }
824
+ });
825
+
826
+ // lib/v3/understudy/a11y/snapshot/focusSelectors.ts
827
+ function parseXPathToSteps(path8) {
828
+ const s2 = path8.trim();
829
+ let i2 = 0;
830
+ const steps = [];
831
+ while (i2 < s2.length) {
832
+ let axis = "child";
833
+ if (s2.startsWith("//", i2)) {
834
+ axis = "desc";
835
+ i2 += 2;
836
+ } else if (s2[i2] === "/") {
837
+ axis = "child";
838
+ i2 += 1;
839
+ }
840
+ const start = i2;
841
+ while (i2 < s2.length && s2[i2] !== "/") i2++;
842
+ const raw = s2.slice(start, i2).trim();
843
+ if (!raw) continue;
844
+ const name = raw.replace(/\[\d+\]\s*$/u, "").toLowerCase();
845
+ steps.push({ axis, raw, name });
846
+ }
847
+ return steps;
848
+ }
849
+ function buildXPathFromSteps(steps) {
850
+ let out = "";
851
+ for (const st of steps) {
852
+ out += st.axis === "desc" ? "//" : "/";
853
+ out += st.raw;
854
+ }
855
+ return out || "/";
856
+ }
857
+ function resolveFocusFrameAndTail(page, absoluteXPath, parentByFrame, rootId) {
1024
858
  return __async(this, null, function* () {
1025
- var _a4, _b;
1026
- const stack = [root];
1027
- const expandedNodeIds = /* @__PURE__ */ new Set();
1028
- const expandedBackendIds = /* @__PURE__ */ new Set();
1029
- while (stack.length) {
1030
- const node = stack.pop();
1031
- const nodeId = typeof node.nodeId === "number" && node.nodeId > 0 ? node.nodeId : void 0;
1032
- const backendId = typeof node.backendNodeId === "number" && node.backendNodeId > 0 ? node.backendNodeId : void 0;
1033
- const seenByNode = nodeId ? expandedNodeIds.has(nodeId) : false;
1034
- const seenByBackend = !nodeId && backendId ? expandedBackendIds.has(backendId) : false;
1035
- if (seenByNode || seenByBackend) continue;
1036
- if (nodeId) expandedNodeIds.add(nodeId);
1037
- else if (backendId) expandedBackendIds.add(backendId);
1038
- const needsExpansion = shouldExpandNode(node);
1039
- if (needsExpansion && (nodeId || backendId)) {
1040
- const describeParamsBase = nodeId ? { nodeId } : { backendNodeId: backendId };
1041
- let expanded = false;
1042
- for (const depth of DESCRIBE_DEPTH_ATTEMPTS) {
859
+ const steps = parseXPathToSteps(absoluteXPath);
860
+ let ctxFrameId = rootId;
861
+ let buf = [];
862
+ let absPrefix = "";
863
+ const flushIntoChild = () => __async(null, null, function* () {
864
+ if (!buf.length) return;
865
+ const selectorForIframe = buildXPathFromSteps(buf);
866
+ const parentSess = page.getSessionForFrame(ctxFrameId);
867
+ const objectId = yield resolveObjectIdForXPath(
868
+ parentSess,
869
+ selectorForIframe,
870
+ ctxFrameId
871
+ );
872
+ if (!objectId)
873
+ throw new StagehandIframeError(
874
+ selectorForIframe,
875
+ "Failed to resolve iframe element by XPath"
876
+ );
877
+ try {
878
+ yield parentSess.send("DOM.enable").catch(() => {
879
+ });
880
+ const desc = yield parentSess.send(
881
+ "DOM.describeNode",
882
+ { objectId }
883
+ );
884
+ const iframeBackendNodeId = desc.node.backendNodeId;
885
+ let childFrameId;
886
+ for (const fid of listChildrenOf(parentByFrame, ctxFrameId)) {
1043
887
  try {
1044
- const described = yield session.send(
1045
- "DOM.describeNode",
1046
- __spreadProps(__spreadValues({}, describeParamsBase), {
1047
- depth,
1048
- pierce
1049
- })
1050
- );
1051
- mergeDomNodes(node, described.node);
1052
- if (!nodeId && described.node.nodeId && described.node.nodeId > 0) {
1053
- node.nodeId = described.node.nodeId;
1054
- expandedNodeIds.add(described.node.nodeId);
1055
- }
1056
- expanded = true;
1057
- break;
1058
- } catch (err) {
1059
- const message = err instanceof Error ? err.message : String(err);
1060
- if (isCborStackError(message)) {
1061
- continue;
888
+ const { backendNodeId } = yield parentSess.send("DOM.getFrameOwner", { frameId: fid });
889
+ if (backendNodeId === iframeBackendNodeId) {
890
+ childFrameId = fid;
891
+ break;
1062
892
  }
1063
- const identifier = (_a4 = nodeId != null ? nodeId : backendId) != null ? _a4 : "unknown";
1064
- throw new StagehandDomProcessError(
1065
- `Failed to expand DOM node ${identifier}: ${String(err)}`
1066
- );
893
+ } catch (e2) {
894
+ continue;
1067
895
  }
1068
896
  }
1069
- if (!expanded) {
1070
- const identifier = (_b = nodeId != null ? nodeId : backendId) != null ? _b : "unknown";
1071
- throw new StagehandDomProcessError(
1072
- `Unable to expand DOM node ${identifier} after describeNode depth retries`
897
+ if (!childFrameId)
898
+ throw new StagehandIframeError(
899
+ selectorForIframe,
900
+ "Could not map iframe to child frameId"
1073
901
  );
1074
- }
902
+ absPrefix = prefixXPath(absPrefix || "/", selectorForIframe);
903
+ ctxFrameId = childFrameId;
904
+ } finally {
905
+ yield parentSess.send("Runtime.releaseObject", { objectId }).catch(() => {
906
+ });
1075
907
  }
1076
- for (const child of collectDomTraversalTargets(node)) {
1077
- stack.push(child);
908
+ buf = [];
909
+ });
910
+ for (const st of steps) {
911
+ buf.push(st);
912
+ if (IFRAME_STEP_RE.test(st.name)) {
913
+ yield flushIntoChild();
1078
914
  }
1079
915
  }
916
+ const tailXPath = buildXPathFromSteps(buf);
917
+ return { targetFrameId: ctxFrameId, tailXPath, absPrefix };
1080
918
  });
1081
919
  }
1082
- function getDomTreeWithFallback(session, pierce) {
920
+ function resolveCssFocusFrameAndTail(page, rawSelector, parentByFrame, rootId) {
1083
921
  return __async(this, null, function* () {
1084
- let lastCborMessage = "";
1085
- for (const depth of DOM_DEPTH_ATTEMPTS) {
1086
- try {
1087
- const { root } = yield session.send(
1088
- "DOM.getDocument",
1089
- { depth, pierce }
1090
- );
1091
- if (depth !== -1) {
1092
- yield hydrateDomTree(session, root, pierce);
1093
- }
1094
- return root;
1095
- } catch (err) {
1096
- const message = err instanceof Error ? err.message : String(err);
1097
- if (isCborStackError(message)) {
1098
- lastCborMessage = message;
1099
- continue;
1100
- }
1101
- throw err;
1102
- }
1103
- }
1104
- throw new StagehandDomProcessError(
1105
- lastCborMessage ? `CDP DOM.getDocument failed after adaptive depth retries: ${lastCborMessage}` : "CDP DOM.getDocument failed after adaptive depth retries."
1106
- );
1107
- });
1108
- }
1109
- function captureHybridSnapshot(page, options) {
1110
- return __async(this, null, function* () {
1111
- var _a4, _b, _c, _d2, _e, _f, _g, _h, _i, _j, _k, _l;
1112
- const pierce = (_a4 = options == null ? void 0 : options.pierceShadow) != null ? _a4 : true;
1113
- const rootId = page.mainFrameId();
1114
- const frameTree = page.asProtocolFrameTree(rootId);
1115
- const parentByFrame = /* @__PURE__ */ new Map();
1116
- (function index(n, parent) {
1117
- var _a5;
1118
- parentByFrame.set(n.frame.id, parent);
1119
- for (const c of (_a5 = n.childFrames) != null ? _a5 : []) index(c, n.frame.id);
1120
- })(frameTree, null);
1121
- const frames = page.listAllFrameIds();
1122
- const combinedXpathMap = {};
1123
- const combinedUrlMap = {};
1124
- const perFrameOutlines = [];
1125
- const perFrameMaps = /* @__PURE__ */ new Map();
1126
- const requestedFocus = (_b = options == null ? void 0 : options.focusSelector) == null ? void 0 : _b.trim();
1127
- if (requestedFocus) {
1128
- const logScopeFallback = () => {
1129
- var _a5;
1130
- v3Logger({
1131
- message: `Unable to narrow scope with selector. Falling back to using full DOM`,
1132
- level: 1,
1133
- auxiliary: {
1134
- arguments: {
1135
- value: `selector: ${(_a5 = options == null ? void 0 : options.focusSelector) == null ? void 0 : _a5.trim()}`,
1136
- type: "string"
1137
- }
1138
- }
1139
- });
1140
- };
1141
- try {
1142
- let targetFrameId;
1143
- let tailSelector;
1144
- let absPrefix2;
1145
- const looksLikeXPath = /^xpath=/i.test(requestedFocus) || requestedFocus.startsWith("/");
1146
- if (looksLikeXPath) {
1147
- const focus = normalizeXPath(requestedFocus);
1148
- const hit = yield resolveFocusFrameAndTail(
1149
- page,
1150
- focus,
1151
- parentByFrame,
1152
- rootId
1153
- );
1154
- targetFrameId = hit.targetFrameId;
1155
- tailSelector = hit.tailXPath || void 0;
1156
- absPrefix2 = hit.absPrefix;
1157
- } else {
1158
- const cssHit = yield resolveCssFocusFrameAndTail(
1159
- page,
1160
- requestedFocus,
1161
- parentByFrame,
1162
- rootId
1163
- );
1164
- targetFrameId = cssHit.targetFrameId;
1165
- tailSelector = cssHit.tailSelector || void 0;
1166
- absPrefix2 = cssHit.absPrefix;
1167
- }
1168
- const owningSess = ownerSession(page, targetFrameId);
1169
- const parentId = parentByFrame.get(targetFrameId);
1170
- const sameSessionAsParent = !!parentId && ownerSession(page, parentId) === ownerSession(page, targetFrameId);
1171
- const { tagNameMap, xpathMap, scrollableMap } = yield domMapsForSession(
1172
- owningSess,
1173
- targetFrameId,
1174
- pierce,
1175
- (fid, be) => `${page.getOrdinal(fid)}-${be}`,
1176
- /*attemptOwnerLookup=*/
1177
- sameSessionAsParent
1178
- );
1179
- const { outline, urlMap, scopeApplied } = yield a11yForFrame(
1180
- owningSess,
1181
- targetFrameId,
1182
- {
1183
- focusSelector: tailSelector || void 0,
1184
- tagNameMap,
1185
- experimental: (_c = options == null ? void 0 : options.experimental) != null ? _c : false,
1186
- scrollableMap,
1187
- encode: (backendNodeId) => `${page.getOrdinal(targetFrameId)}-${backendNodeId}`
1188
- }
1189
- );
1190
- const combinedXpathMap2 = {};
1191
- const abs = absPrefix2 != null ? absPrefix2 : "";
1192
- const isRoot = !abs || abs === "/";
1193
- if (isRoot) {
1194
- Object.assign(combinedXpathMap2, xpathMap);
1195
- } else {
1196
- for (const [encId, xp] of Object.entries(xpathMap)) {
1197
- combinedXpathMap2[encId] = prefixXPath(abs, xp);
1198
- }
1199
- }
1200
- const combinedUrlMap2 = __spreadValues({}, urlMap);
1201
- const snapshot = {
1202
- combinedTree: outline,
1203
- combinedXpathMap: combinedXpathMap2,
1204
- combinedUrlMap: combinedUrlMap2,
1205
- perFrame: [
1206
- {
1207
- frameId: targetFrameId,
1208
- outline,
1209
- xpathMap,
1210
- urlMap
1211
- }
1212
- ]
1213
- };
1214
- if (scopeApplied) {
1215
- return snapshot;
1216
- }
1217
- logScopeFallback();
1218
- } catch (e2) {
1219
- logScopeFallback();
1220
- }
1221
- }
1222
- function buildSessionDomIndex(session, pierce2) {
1223
- return __async(this, null, function* () {
1224
- var _a5, _b2;
1225
- yield session.send("DOM.enable").catch(() => {
1226
- });
1227
- const root = yield getDomTreeWithFallback(session, pierce2);
1228
- const absByBe = /* @__PURE__ */ new Map();
1229
- const tagByBe = /* @__PURE__ */ new Map();
1230
- const scrollByBe = /* @__PURE__ */ new Map();
1231
- const docRootOf = /* @__PURE__ */ new Map();
1232
- const contentDocRootByIframe = /* @__PURE__ */ new Map();
1233
- const rootBe = root.backendNodeId;
1234
- const stack = [{ node: root, xp: "/", docRootBe: rootBe }];
1235
- while (stack.length) {
1236
- const { node, xp, docRootBe } = stack.pop();
1237
- if (node.backendNodeId) {
1238
- absByBe.set(node.backendNodeId, xp || "/");
1239
- tagByBe.set(node.backendNodeId, String(node.nodeName).toLowerCase());
1240
- if ((node == null ? void 0 : node.isScrollable) === true)
1241
- scrollByBe.set(node.backendNodeId, true);
1242
- docRootOf.set(node.backendNodeId, docRootBe);
1243
- }
1244
- const kids = (_a5 = node.children) != null ? _a5 : [];
1245
- if (kids.length) {
1246
- const segs = buildChildXPathSegments(kids);
1247
- for (let i2 = kids.length - 1; i2 >= 0; i2--) {
1248
- const child = kids[i2];
1249
- const step = segs[i2];
1250
- stack.push({ node: child, xp: joinXPath(xp, step), docRootBe });
1251
- }
1252
- }
1253
- for (const sr of (_b2 = node.shadowRoots) != null ? _b2 : []) {
1254
- stack.push({ node: sr, xp: joinXPath(xp, "//"), docRootBe });
1255
- }
1256
- const cd = node.contentDocument;
1257
- if (cd && typeof cd.backendNodeId === "number") {
1258
- contentDocRootByIframe.set(node.backendNodeId, cd.backendNodeId);
1259
- stack.push({ node: cd, xp, docRootBe: cd.backendNodeId });
1260
- }
1261
- }
1262
- return {
1263
- rootBackend: rootBe,
1264
- absByBe,
1265
- tagByBe,
1266
- scrollByBe,
1267
- docRootOf,
1268
- contentDocRootByIframe
1269
- };
1270
- });
1271
- }
1272
- function relativizeXPath(baseAbs, nodeAbs) {
1273
- const base = normalizeXPath(baseAbs);
1274
- const abs = normalizeXPath(nodeAbs);
1275
- if (abs === base) return "/";
1276
- if (abs.startsWith(base)) {
1277
- const tail = abs.slice(base.length);
1278
- if (!tail) return "/";
1279
- return tail.startsWith("/") || tail.startsWith("//") ? tail : `/${tail}`;
1280
- }
1281
- if (base === "/") return abs;
1282
- return abs;
1283
- }
1284
- const sessionToIndex = /* @__PURE__ */ new Map();
1285
- const sessionById = /* @__PURE__ */ new Map();
1286
- for (const frameId of frames) {
1287
- const sess = ownerSession(page, frameId);
1288
- const sid = (_d2 = sess.id) != null ? _d2 : "root";
1289
- if (!sessionById.has(sid)) sessionById.set(sid, sess);
1290
- }
1291
- for (const [sid, sess] of sessionById.entries()) {
1292
- const idx = yield buildSessionDomIndex(sess, pierce);
1293
- sessionToIndex.set(sid, idx);
1294
- }
1295
- for (const frameId of frames) {
1296
- const sess = ownerSession(page, frameId);
1297
- const sid = (_e = sess.id) != null ? _e : "root";
1298
- let idx = sessionToIndex.get(sid);
1299
- if (!idx) {
1300
- idx = yield buildSessionDomIndex(sess, pierce);
1301
- sessionToIndex.set(sid, idx);
1302
- }
1303
- const parentId = parentByFrame.get(frameId);
1304
- const sameSessionAsParent = !!parentId && ownerSession(page, parentId) === sess;
1305
- let docRootBe = idx.rootBackend;
1306
- if (sameSessionAsParent) {
1307
- try {
1308
- const { backendNodeId } = yield sess.send(
1309
- "DOM.getFrameOwner",
1310
- { frameId }
1311
- );
1312
- if (typeof backendNodeId === "number") {
1313
- const cdBe = idx.contentDocRootByIframe.get(backendNodeId);
1314
- if (typeof cdBe === "number") docRootBe = cdBe;
1315
- }
1316
- } catch (e2) {
1317
- }
1318
- }
1319
- const tagNameMap = {};
1320
- const xpathMap = {};
1321
- const scrollableMap = {};
1322
- const enc = (be) => `${page.getOrdinal(frameId)}-${be}`;
1323
- const baseAbs = (_f = idx.absByBe.get(docRootBe)) != null ? _f : "/";
1324
- for (const [be, nodeAbs] of idx.absByBe.entries()) {
1325
- const nodeDocRoot = idx.docRootOf.get(be);
1326
- if (nodeDocRoot !== docRootBe) continue;
1327
- const rel = relativizeXPath(baseAbs, nodeAbs);
1328
- const key = enc(be);
1329
- xpathMap[key] = rel;
1330
- const tag = idx.tagByBe.get(be);
1331
- if (tag) tagNameMap[key] = tag;
1332
- if (idx.scrollByBe.get(be)) scrollableMap[key] = true;
1333
- }
1334
- const { outline, urlMap } = yield a11yForFrame(sess, frameId, {
1335
- experimental: (_g = options == null ? void 0 : options.experimental) != null ? _g : false,
1336
- tagNameMap,
1337
- scrollableMap,
1338
- encode: (backendNodeId) => `${page.getOrdinal(frameId)}-${backendNodeId}`
1339
- });
1340
- perFrameOutlines.push({ frameId, outline });
1341
- perFrameMaps.set(frameId, { tagNameMap, xpathMap, scrollableMap, urlMap });
1342
- }
1343
- const absPrefix = /* @__PURE__ */ new Map();
1344
- const iframeHostEncByChild = /* @__PURE__ */ new Map();
1345
- absPrefix.set(rootId, "");
1346
- const queue = [rootId];
1347
- while (queue.length) {
1348
- const parent = queue.shift();
1349
- const parentAbs = absPrefix.get(parent);
1350
- for (const child of frames) {
1351
- if (parentByFrame.get(child) !== parent) continue;
1352
- queue.push(child);
1353
- const parentSess = parentSession(page, parentByFrame, child);
1354
- const ownerBackendNodeId = yield (() => __async(null, null, function* () {
1355
- try {
1356
- const { backendNodeId } = yield parentSess.send("DOM.getFrameOwner", { frameId: child });
1357
- return backendNodeId;
1358
- } catch (e2) {
1359
- return void 0;
1360
- }
1361
- }))();
1362
- if (!ownerBackendNodeId) {
1363
- absPrefix.set(child, parentAbs);
1364
- continue;
1365
- }
1366
- const parentDom = perFrameMaps.get(parent);
1367
- const iframeEnc = `${page.getOrdinal(parent)}-${ownerBackendNodeId}`;
1368
- const iframeXPath = parentDom == null ? void 0 : parentDom.xpathMap[iframeEnc];
1369
- const childAbs = iframeXPath ? prefixXPath(parentAbs || "/", iframeXPath) : parentAbs;
1370
- absPrefix.set(child, childAbs);
1371
- iframeHostEncByChild.set(child, iframeEnc);
1372
- }
1373
- }
1374
- for (const frameId of frames) {
1375
- const maps = perFrameMaps.get(frameId);
1376
- if (!maps) continue;
1377
- const abs = (_h = absPrefix.get(frameId)) != null ? _h : "";
1378
- const isRoot = abs === "" || abs === "/";
1379
- if (isRoot) {
1380
- Object.assign(combinedXpathMap, maps.xpathMap);
1381
- Object.assign(combinedUrlMap, maps.urlMap);
1382
- continue;
1383
- }
1384
- for (const [encId, xp] of Object.entries(maps.xpathMap)) {
1385
- combinedXpathMap[encId] = prefixXPath(abs, xp);
1386
- }
1387
- Object.assign(combinedUrlMap, maps.urlMap);
1388
- }
1389
- const idToTree = /* @__PURE__ */ new Map();
1390
- for (const { frameId, outline } of perFrameOutlines) {
1391
- const parentEnc = iframeHostEncByChild.get(frameId);
1392
- if (parentEnc) idToTree.set(parentEnc, outline);
1393
- }
1394
- const rootOutline = (_l = (_k = (_i = perFrameOutlines.find((o) => o.frameId === rootId)) == null ? void 0 : _i.outline) != null ? _k : (_j = perFrameOutlines[0]) == null ? void 0 : _j.outline) != null ? _l : "";
1395
- const combinedTree = injectSubtrees(rootOutline, idToTree);
1396
- return {
1397
- combinedTree,
1398
- combinedXpathMap,
1399
- combinedUrlMap,
1400
- perFrame: perFrameOutlines.map(({ frameId, outline }) => {
1401
- var _a5, _b2;
1402
- const maps = perFrameMaps.get(frameId);
1403
- return {
1404
- frameId,
1405
- outline,
1406
- xpathMap: (_a5 = maps == null ? void 0 : maps.xpathMap) != null ? _a5 : {},
1407
- urlMap: (_b2 = maps == null ? void 0 : maps.urlMap) != null ? _b2 : {}
1408
- };
1409
- })
1410
- };
1411
- });
1412
- }
1413
- function prefixXPath(parentAbs, child) {
1414
- const p = parentAbs === "/" ? "" : parentAbs.replace(/\/$/, "");
1415
- if (!child || child === "/") return p || "/";
1416
- if (child.startsWith("//"))
1417
- return p ? `${p}//${child.slice(2)}` : `//${child.slice(2)}`;
1418
- const c = child.replace(/^\//, "");
1419
- return p ? `${p}/${c}` : `/${c}`;
1420
- }
1421
- function normalizeXPath(x2) {
1422
- if (!x2) return "";
1423
- let s2 = x2.trim().replace(/^xpath=/i, "");
1424
- if (!s2.startsWith("/")) s2 = "/" + s2;
1425
- if (s2.length > 1 && s2.endsWith("/")) s2 = s2.slice(0, -1);
1426
- return s2;
1427
- }
1428
- function parseXPathToSteps(path8) {
1429
- const s2 = path8.trim();
1430
- let i2 = 0;
1431
- const steps = [];
1432
- while (i2 < s2.length) {
1433
- let axis = "child";
1434
- if (s2.startsWith("//", i2)) {
1435
- axis = "desc";
1436
- i2 += 2;
1437
- } else if (s2[i2] === "/") {
1438
- axis = "child";
1439
- i2 += 1;
1440
- }
1441
- const start = i2;
1442
- while (i2 < s2.length && s2[i2] !== "/") i2++;
1443
- const raw = s2.slice(start, i2).trim();
1444
- if (!raw) continue;
1445
- const name = raw.replace(/\[\d+\]\s*$/u, "").toLowerCase();
1446
- steps.push({ axis, raw, name });
1447
- }
1448
- return steps;
1449
- }
1450
- function buildXPathFromSteps(steps) {
1451
- let out = "";
1452
- for (const st of steps) {
1453
- out += st.axis === "desc" ? "//" : "/";
1454
- out += st.raw;
1455
- }
1456
- return out || "/";
1457
- }
1458
- function resolveFocusFrameAndTail(page, absoluteXPath, parentByFrame, rootId) {
1459
- return __async(this, null, function* () {
1460
- const steps = parseXPathToSteps(absoluteXPath);
922
+ var _a4;
923
+ const parts = rawSelector.split(">>").map((s2) => s2.trim()).filter(Boolean);
1461
924
  let ctxFrameId = rootId;
1462
- let buf = [];
1463
- let absPrefix = "";
1464
- const flushIntoChild = () => __async(null, null, function* () {
1465
- if (!buf.length) return;
1466
- const selectorForIframe = buildXPathFromSteps(buf);
925
+ const absPrefix = "";
926
+ for (let i2 = 0; i2 < Math.max(0, parts.length - 1); i2++) {
1467
927
  const parentSess = page.getSessionForFrame(ctxFrameId);
1468
- const objectId = yield resolveObjectIdForXPath(
928
+ const objectId = yield resolveObjectIdForCss(
1469
929
  parentSess,
1470
- selectorForIframe,
930
+ parts[i2],
1471
931
  ctxFrameId
1472
932
  );
1473
933
  if (!objectId)
1474
934
  throw new StagehandIframeError(
1475
- selectorForIframe,
1476
- "Failed to resolve iframe element by XPath"
935
+ parts[i2],
936
+ "Failed to resolve iframe via CSS hop"
1477
937
  );
1478
938
  try {
1479
939
  yield parentSess.send("DOM.enable").catch(() => {
@@ -1492,246 +952,22 @@ function resolveFocusFrameAndTail(page, absoluteXPath, parentByFrame, rootId) {
1492
952
  break;
1493
953
  }
1494
954
  } catch (e2) {
955
+ continue;
1495
956
  }
1496
957
  }
1497
958
  if (!childFrameId)
1498
959
  throw new StagehandIframeError(
1499
- selectorForIframe,
1500
- "Could not map iframe to child frameId"
960
+ parts[i2],
961
+ "Could not map CSS iframe hop to child frameId"
1501
962
  );
1502
- absPrefix = prefixXPath(absPrefix || "/", selectorForIframe);
1503
963
  ctxFrameId = childFrameId;
1504
964
  } finally {
1505
965
  yield parentSess.send("Runtime.releaseObject", { objectId }).catch(() => {
1506
966
  });
1507
967
  }
1508
- buf = [];
1509
- });
1510
- for (const st of steps) {
1511
- buf.push(st);
1512
- if (IFRAME_STEP_RE.test(st.name)) {
1513
- yield flushIntoChild();
1514
- }
1515
968
  }
1516
- const tailXPath = buildXPathFromSteps(buf);
1517
- return { targetFrameId: ctxFrameId, tailXPath, absPrefix };
1518
- });
1519
- }
1520
- function resolveCssFocusFrameAndTail(page, rawSelector, parentByFrame, rootId) {
1521
- return __async(this, null, function* () {
1522
- var _a4;
1523
- const parts = rawSelector.split(">>").map((s2) => s2.trim()).filter(Boolean);
1524
- let ctxFrameId = rootId;
1525
- const absPrefix = "";
1526
- for (let i2 = 0; i2 < Math.max(0, parts.length - 1); i2++) {
1527
- const parentSess = page.getSessionForFrame(ctxFrameId);
1528
- const objectId = yield resolveObjectIdForCss(
1529
- parentSess,
1530
- parts[i2],
1531
- ctxFrameId
1532
- );
1533
- if (!objectId)
1534
- throw new StagehandIframeError(
1535
- parts[i2],
1536
- "Failed to resolve iframe via CSS hop"
1537
- );
1538
- try {
1539
- yield parentSess.send("DOM.enable").catch(() => {
1540
- });
1541
- const desc = yield parentSess.send(
1542
- "DOM.describeNode",
1543
- { objectId }
1544
- );
1545
- const iframeBackendNodeId = desc.node.backendNodeId;
1546
- let childFrameId;
1547
- for (const fid of listChildrenOf(parentByFrame, ctxFrameId)) {
1548
- try {
1549
- const { backendNodeId } = yield parentSess.send("DOM.getFrameOwner", { frameId: fid });
1550
- if (backendNodeId === iframeBackendNodeId) {
1551
- childFrameId = fid;
1552
- break;
1553
- }
1554
- } catch (e2) {
1555
- }
1556
- }
1557
- if (!childFrameId)
1558
- throw new StagehandIframeError(
1559
- parts[i2],
1560
- "Could not map CSS iframe hop to child frameId"
1561
- );
1562
- ctxFrameId = childFrameId;
1563
- } finally {
1564
- yield parentSess.send("Runtime.releaseObject", { objectId }).catch(() => {
1565
- });
1566
- }
1567
- }
1568
- const tailSelector = (_a4 = parts[parts.length - 1]) != null ? _a4 : "*";
1569
- return { targetFrameId: ctxFrameId, tailSelector, absPrefix };
1570
- });
1571
- }
1572
- function listChildrenOf(parentByFrame, parentId) {
1573
- const out = [];
1574
- for (const [fid, p] of parentByFrame.entries()) {
1575
- if (p === parentId) out.push(fid);
1576
- }
1577
- return out;
1578
- }
1579
- function domMapsForSession(session, frameId, pierce, encode = (fid, be) => `${fid}-${be}`, attemptOwnerLookup = true) {
1580
- return __async(this, null, function* () {
1581
- var _a4, _b;
1582
- yield session.send("DOM.enable").catch(() => {
1583
- });
1584
- const root = yield getDomTreeWithFallback(session, pierce);
1585
- let startNode = root;
1586
- if (attemptOwnerLookup) {
1587
- try {
1588
- const owner = yield session.send(
1589
- "DOM.getFrameOwner",
1590
- { frameId }
1591
- );
1592
- const ownerBackendId = owner.backendNodeId;
1593
- if (typeof ownerBackendId === "number") {
1594
- const ownerEl = findNodeByBackendId(root, ownerBackendId);
1595
- if (ownerEl == null ? void 0 : ownerEl.contentDocument) {
1596
- startNode = ownerEl.contentDocument;
1597
- }
1598
- }
1599
- } catch (e2) {
1600
- }
1601
- }
1602
- const tagNameMap = {};
1603
- const xpathMap = {};
1604
- const scrollableMap = {};
1605
- const stack = [{ node: startNode, xpath: "" }];
1606
- while (stack.length) {
1607
- const { node, xpath } = stack.pop();
1608
- if (node.backendNodeId) {
1609
- const encId = encode(frameId, node.backendNodeId);
1610
- tagNameMap[encId] = String(node.nodeName).toLowerCase();
1611
- xpathMap[encId] = xpath || "/";
1612
- const isScrollable = (node == null ? void 0 : node.isScrollable) === true;
1613
- if (isScrollable) scrollableMap[encId] = true;
1614
- }
1615
- const kids = (_a4 = node.children) != null ? _a4 : [];
1616
- if (kids.length) {
1617
- const segs = buildChildXPathSegments(kids);
1618
- for (let i2 = kids.length - 1; i2 >= 0; i2--) {
1619
- const child = kids[i2];
1620
- const step = segs[i2];
1621
- stack.push({
1622
- node: child,
1623
- xpath: joinXPath(xpath, step)
1624
- });
1625
- }
1626
- }
1627
- for (const sr of (_b = node.shadowRoots) != null ? _b : []) {
1628
- stack.push({
1629
- node: sr,
1630
- xpath: joinXPath(xpath, "//")
1631
- });
1632
- }
1633
- }
1634
- return { tagNameMap, xpathMap, scrollableMap };
1635
- });
1636
- }
1637
- function buildChildXPathSegments(kids) {
1638
- var _a4;
1639
- const segs = [];
1640
- const ctr = {};
1641
- for (const child of kids) {
1642
- const tag = String(child.nodeName).toLowerCase();
1643
- const key = `${child.nodeType}:${tag}`;
1644
- const idx = ctr[key] = ((_a4 = ctr[key]) != null ? _a4 : 0) + 1;
1645
- if (child.nodeType === 3) {
1646
- segs.push(`text()[${idx}]`);
1647
- } else if (child.nodeType === 8) {
1648
- segs.push(`comment()[${idx}]`);
1649
- } else {
1650
- segs.push(
1651
- tag.includes(":") ? `*[name()='${tag}'][${idx}]` : `${tag}[${idx}]`
1652
- );
1653
- }
1654
- }
1655
- return segs;
1656
- }
1657
- function joinXPath(base, step) {
1658
- if (step === "//") {
1659
- if (!base || base === "/") return "//";
1660
- return base.endsWith("/") ? `${base}/` : `${base}//`;
1661
- }
1662
- if (!base || base === "/") return step ? `/${step}` : "/";
1663
- if (base.endsWith("//")) return `${base}${step}`;
1664
- if (!step) return base;
1665
- return `${base}/${step}`;
1666
- }
1667
- function a11yForFrame(session, frameId, opts) {
1668
- return __async(this, null, function* () {
1669
- var _a4, _b;
1670
- yield session.send("Accessibility.enable").catch(() => {
1671
- });
1672
- yield session.send("Runtime.enable").catch(() => {
1673
- });
1674
- yield session.send("DOM.enable").catch(() => {
1675
- });
1676
- let nodes = [];
1677
- try {
1678
- const params = frameId ? { frameId } : {};
1679
- ({ nodes } = yield session.send("Accessibility.getFullAXTree", params));
1680
- } catch (e2) {
1681
- const msg = String((_b = (_a4 = e2 == null ? void 0 : e2.message) != null ? _a4 : e2) != null ? _b : "");
1682
- const isFrameScopeError = msg.includes("Frame with the given") || msg.includes("does not belong to the target") || msg.includes("is not found");
1683
- if (!isFrameScopeError || !frameId) throw e2;
1684
- ({ nodes } = yield session.send("Accessibility.getFullAXTree"));
1685
- }
1686
- const urlMap = {};
1687
- for (const n of nodes) {
1688
- const be = n.backendDOMNodeId;
1689
- if (typeof be !== "number") continue;
1690
- const url = extractUrlFromAXNode(n);
1691
- if (!url) continue;
1692
- const enc = opts.encode(be);
1693
- urlMap[enc] = url;
1694
- }
1695
- let scopeApplied = false;
1696
- const nodesForOutline = yield (() => __async(null, null, function* () {
1697
- var _a5, _b2, _c;
1698
- const sel = (_a5 = opts.focusSelector) == null ? void 0 : _a5.trim();
1699
- if (!sel) return nodes;
1700
- try {
1701
- const looksLikeXPath = /^xpath=/i.test(sel) || sel.startsWith("/");
1702
- const objectId = looksLikeXPath ? yield resolveObjectIdForXPath(session, sel, frameId) : yield resolveObjectIdForCss(session, sel, frameId);
1703
- if (!objectId) return nodes;
1704
- const desc = yield session.send(
1705
- "DOM.describeNode",
1706
- { objectId }
1707
- );
1708
- const be = (_b2 = desc.node) == null ? void 0 : _b2.backendNodeId;
1709
- if (typeof be !== "number") return nodes;
1710
- const target = nodes.find((n) => n.backendDOMNodeId === be);
1711
- if (!target) return nodes;
1712
- scopeApplied = true;
1713
- const keep = /* @__PURE__ */ new Set([target.nodeId]);
1714
- const queue = [target];
1715
- while (queue.length) {
1716
- const cur = queue.shift();
1717
- for (const id of (_c = cur.childIds) != null ? _c : []) {
1718
- if (keep.has(id)) continue;
1719
- keep.add(id);
1720
- const child = nodes.find((n) => n.nodeId === id);
1721
- if (child) queue.push(child);
1722
- }
1723
- }
1724
- return nodes.filter((n) => keep.has(n.nodeId)).map(
1725
- (n) => n.nodeId === target.nodeId ? __spreadProps(__spreadValues({}, n), { parentId: void 0 }) : n
1726
- );
1727
- } catch (e2) {
1728
- return nodes;
1729
- }
1730
- }))();
1731
- const decorated = decorateRoles(nodesForOutline, opts);
1732
- const { tree } = yield buildHierarchicalTree(decorated, opts);
1733
- const simplified = tree.map((n) => formatTreeLine(n)).join("\n");
1734
- return { outline: simplified.trimEnd(), urlMap, scopeApplied };
969
+ const tailSelector = (_a4 = parts[parts.length - 1]) != null ? _a4 : "*";
970
+ return { targetFrameId: ctxFrameId, tailSelector, absPrefix };
1735
971
  });
1736
972
  }
1737
973
  function resolveObjectIdForXPath(session, xpath, frameId) {
@@ -1803,89 +1039,25 @@ function resolveObjectIdForCss(session, selector, frameId) {
1803
1039
  return evaluate(fallbackExpr);
1804
1040
  });
1805
1041
  }
1806
- function decorateRoles(nodes, opts) {
1807
- const asRole = (n) => {
1808
- var _a4, _b;
1809
- return String((_b = (_a4 = n.role) == null ? void 0 : _a4.value) != null ? _b : "");
1810
- };
1811
- return nodes.map((n) => {
1812
- var _a4, _b, _c;
1813
- let encodedId;
1814
- if (typeof n.backendDOMNodeId === "number") {
1815
- try {
1816
- encodedId = opts.encode(n.backendDOMNodeId);
1817
- } catch (e2) {
1818
- }
1819
- }
1820
- let role = asRole(n);
1821
- const domIsScrollable = encodedId ? opts.scrollableMap[encodedId] === true : false;
1822
- const tag = encodedId ? opts.tagNameMap[encodedId] : void 0;
1823
- const isHtmlElement = tag === "html";
1824
- if ((domIsScrollable || isHtmlElement) && tag !== "#document") {
1825
- const tagLabel = tag && tag.startsWith("#") ? tag.slice(1) : tag;
1826
- role = tagLabel ? `scrollable, ${tagLabel}` : `scrollable${role ? `, ${role}` : ""}`;
1827
- }
1828
- return {
1829
- role,
1830
- name: (_a4 = n.name) == null ? void 0 : _a4.value,
1831
- description: (_b = n.description) == null ? void 0 : _b.value,
1832
- value: (_c = n.value) == null ? void 0 : _c.value,
1833
- nodeId: n.nodeId,
1834
- backendDOMNodeId: n.backendDOMNodeId,
1835
- parentId: n.parentId,
1836
- childIds: n.childIds,
1837
- encodedId
1838
- };
1839
- });
1840
- }
1841
- function buildHierarchicalTree(nodes, opts) {
1842
- return __async(this, null, function* () {
1843
- var _a4;
1844
- const nodeMap = /* @__PURE__ */ new Map();
1845
- for (const n of nodes) {
1846
- const keep = !!(n.name && n.name.trim()) || !!(n.childIds && n.childIds.length) || !isStructural(n.role);
1847
- if (!keep) continue;
1848
- nodeMap.set(n.nodeId, __spreadValues({}, n));
1849
- }
1850
- for (const n of nodes) {
1851
- if (!n.parentId) continue;
1852
- const parent = nodeMap.get(n.parentId);
1853
- const cur = nodeMap.get(n.nodeId);
1854
- if (parent && cur) ((_a4 = parent.children) != null ? _a4 : parent.children = []).push(cur);
1855
- }
1856
- const roots = nodes.filter((n) => !n.parentId && nodeMap.has(n.nodeId)).map((n) => nodeMap.get(n.nodeId));
1857
- const cleaned = (yield Promise.all(roots.map(pruneStructuralSafe))).filter(
1858
- Boolean
1859
- );
1860
- return { tree: cleaned };
1861
- function pruneStructuralSafe(node) {
1862
- return __async(this, null, function* () {
1863
- var _a5;
1864
- if (+node.nodeId < 0) return null;
1865
- const children = (_a5 = node.children) != null ? _a5 : [];
1866
- if (!children.length) {
1867
- return isStructural(node.role) ? null : node;
1868
- }
1869
- const cleanedKids = (yield Promise.all(children.map(pruneStructuralSafe))).filter(Boolean);
1870
- const prunedStatic = removeRedundantStaticTextChildren(node, cleanedKids);
1871
- if (isStructural(node.role)) {
1872
- if (prunedStatic.length === 1) return prunedStatic[0];
1873
- if (prunedStatic.length === 0) return null;
1874
- }
1875
- let newRole = node.role;
1876
- if ((newRole === "generic" || newRole === "none") && node.encodedId) {
1877
- const tagName = opts.tagNameMap[node.encodedId];
1878
- if (tagName) newRole = tagName;
1879
- }
1880
- if (newRole === "combobox" && node.encodedId) {
1881
- const tagName = opts.tagNameMap[node.encodedId];
1882
- if (tagName === "select") newRole = "select";
1883
- }
1884
- return __spreadProps(__spreadValues({}, node), { role: newRole, children: prunedStatic });
1885
- });
1886
- }
1887
- });
1042
+ function listChildrenOf(parentByFrame, parentId) {
1043
+ const out = [];
1044
+ for (const [fid, p] of parentByFrame.entries()) {
1045
+ if (p === parentId) out.push(fid);
1046
+ }
1047
+ return out;
1888
1048
  }
1049
+ var IFRAME_STEP_RE;
1050
+ var init_focusSelectors = __esm({
1051
+ "lib/v3/understudy/a11y/snapshot/focusSelectors.ts"() {
1052
+ init_executionContextRegistry();
1053
+ init_locatorInvocation();
1054
+ init_sdkErrors();
1055
+ init_xpathUtils();
1056
+ IFRAME_STEP_RE = /^iframe(?:\[\d+])?$/i;
1057
+ }
1058
+ });
1059
+
1060
+ // lib/v3/understudy/a11y/snapshot/treeFormatUtils.ts
1889
1061
  function formatTreeLine(node, level = 0) {
1890
1062
  var _a4, _b, _c;
1891
1063
  const indent = " ".repeat(level);
@@ -1895,80 +1067,6 @@ function formatTreeLine(node, level = 0) {
1895
1067
  return kids ? `${indent}${label}
1896
1068
  ${kids}` : `${indent}${label}`;
1897
1069
  }
1898
- function isStructural(role) {
1899
- const r2 = role == null ? void 0 : role.toLowerCase();
1900
- return r2 === "generic" || r2 === "none" || r2 === "inlinetextbox";
1901
- }
1902
- function cleanText(input) {
1903
- const PUA_START = 57344;
1904
- const PUA_END = 63743;
1905
- const NBSP = /* @__PURE__ */ new Set([160, 8239, 8199, 65279]);
1906
- let out = "";
1907
- let prevSpace = false;
1908
- for (let i2 = 0; i2 < input.length; i2++) {
1909
- const code = input.charCodeAt(i2);
1910
- if (code >= PUA_START && code <= PUA_END) continue;
1911
- if (NBSP.has(code)) {
1912
- if (!prevSpace) {
1913
- out += " ";
1914
- prevSpace = true;
1915
- }
1916
- continue;
1917
- }
1918
- out += input[i2];
1919
- prevSpace = input[i2] === " ";
1920
- }
1921
- return out.trim();
1922
- }
1923
- function extractUrlFromAXNode(ax) {
1924
- var _a4, _b;
1925
- const props = (_a4 = ax.properties) != null ? _a4 : [];
1926
- const urlProp = props.find((p) => p.name === "url");
1927
- const value = (_b = urlProp == null ? void 0 : urlProp.value) == null ? void 0 : _b.value;
1928
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
1929
- }
1930
- function normaliseSpaces(s2) {
1931
- let out = "";
1932
- let inWs = false;
1933
- for (let i2 = 0; i2 < s2.length; i2++) {
1934
- const ch = s2[i2];
1935
- const isWs = /\s/.test(ch);
1936
- if (isWs) {
1937
- if (!inWs) {
1938
- out += " ";
1939
- inWs = true;
1940
- }
1941
- } else {
1942
- out += ch;
1943
- inWs = false;
1944
- }
1945
- }
1946
- return out;
1947
- }
1948
- function removeRedundantStaticTextChildren(parent, children) {
1949
- if (!parent.name) return children;
1950
- const parentNorm = normaliseSpaces(parent.name).trim();
1951
- let combined = "";
1952
- for (const c of children) {
1953
- if (c.role === "StaticText" && c.name) {
1954
- combined += normaliseSpaces(c.name).trim();
1955
- }
1956
- }
1957
- if (combined === parentNorm) {
1958
- return children.filter((c) => c.role !== "StaticText");
1959
- }
1960
- return children;
1961
- }
1962
- function findNodeByBackendId(root, backendNodeId) {
1963
- const stack = [root];
1964
- while (stack.length) {
1965
- const n = stack.pop();
1966
- if (n.backendNodeId === backendNodeId) return n;
1967
- if (n.children) for (const c of n.children) stack.push(c);
1968
- if (n.shadowRoots) for (const s2 of n.shadowRoots) stack.push(s2);
1969
- }
1970
- return void 0;
1971
- }
1972
1070
  function injectSubtrees(rootOutline, idToTree) {
1973
1071
  var _a4, _b;
1974
1072
  const out = [];
@@ -2024,29 +1122,1069 @@ function diffCombinedTrees(prevTree, nextTree) {
2024
1122
  );
2025
1123
  return out.join("\n");
2026
1124
  }
2027
- function ownerSession(page, frameId) {
2028
- return page.getSessionForFrame(frameId);
1125
+ function cleanText(input) {
1126
+ const PUA_START = 57344;
1127
+ const PUA_END = 63743;
1128
+ const NBSP = /* @__PURE__ */ new Set([160, 8239, 8199, 65279]);
1129
+ let out = "";
1130
+ let prevSpace = false;
1131
+ for (let i2 = 0; i2 < input.length; i2++) {
1132
+ const code = input.charCodeAt(i2);
1133
+ if (code >= PUA_START && code <= PUA_END) continue;
1134
+ if (NBSP.has(code)) {
1135
+ if (!prevSpace) {
1136
+ out += " ";
1137
+ prevSpace = true;
1138
+ }
1139
+ continue;
1140
+ }
1141
+ out += input[i2];
1142
+ prevSpace = input[i2] === " ";
1143
+ }
1144
+ return out.trim();
2029
1145
  }
2030
- function parentSession(page, parentByFrame, frameId) {
2031
- var _a4;
2032
- const parentId = (_a4 = parentByFrame.get(frameId)) != null ? _a4 : null;
2033
- if (!parentId) {
2034
- return page.getSessionForFrame(frameId);
1146
+ function normaliseSpaces(s2) {
1147
+ let out = "";
1148
+ let inWs = false;
1149
+ for (let i2 = 0; i2 < s2.length; i2++) {
1150
+ const ch = s2[i2];
1151
+ const isWs = /\s/.test(ch);
1152
+ if (isWs) {
1153
+ if (!inWs) {
1154
+ out += " ";
1155
+ inWs = true;
1156
+ }
1157
+ } else {
1158
+ out += ch;
1159
+ inWs = false;
1160
+ }
2035
1161
  }
2036
- return page.getSessionForFrame(parentId);
1162
+ return out;
2037
1163
  }
2038
- var DOM_DEPTH_ATTEMPTS, DESCRIBE_DEPTH_ATTEMPTS, IFRAME_STEP_RE;
2039
- var init_snapshot = __esm({
2040
- "lib/v3/understudy/a11y/snapshot.ts"() {
2041
- init_executionContextRegistry();
2042
- init_logger();
2043
- init_a11yScripts_generated();
2044
- init_a11yInvocation();
2045
- init_locatorInvocation();
2046
- init_sdkErrors();
2047
- DOM_DEPTH_ATTEMPTS = [-1, 256, 128, 64, 32, 16, 8, 4, 2, 1];
2048
- DESCRIBE_DEPTH_ATTEMPTS = [-1, 64, 32, 16, 8, 4, 2, 1];
2049
- IFRAME_STEP_RE = /^iframe(?:\[\d+])?$/i;
1164
+ var init_treeFormatUtils = __esm({
1165
+ "lib/v3/understudy/a11y/snapshot/treeFormatUtils.ts"() {
1166
+ }
1167
+ });
1168
+
1169
+ // lib/v3/understudy/a11y/snapshot/a11yTree.ts
1170
+ function a11yForFrame(session, frameId, opts) {
1171
+ return __async(this, null, function* () {
1172
+ var _a4, _b;
1173
+ yield session.send("Accessibility.enable").catch(() => {
1174
+ });
1175
+ yield session.send("Runtime.enable").catch(() => {
1176
+ });
1177
+ yield session.send("DOM.enable").catch(() => {
1178
+ });
1179
+ let nodes = [];
1180
+ try {
1181
+ const params = frameId ? { frameId } : {};
1182
+ ({ nodes } = yield session.send("Accessibility.getFullAXTree", params));
1183
+ } catch (e2) {
1184
+ const msg = String((_b = (_a4 = e2 == null ? void 0 : e2.message) != null ? _a4 : e2) != null ? _b : "");
1185
+ const isFrameScopeError = msg.includes("Frame with the given") || msg.includes("does not belong to the target") || msg.includes("is not found");
1186
+ if (!isFrameScopeError || !frameId) throw e2;
1187
+ ({ nodes } = yield session.send("Accessibility.getFullAXTree"));
1188
+ }
1189
+ const urlMap = {};
1190
+ for (const n of nodes) {
1191
+ const be = n.backendDOMNodeId;
1192
+ if (typeof be !== "number") continue;
1193
+ const url = extractUrlFromAXNode(n);
1194
+ if (!url) continue;
1195
+ const enc = opts.encode(be);
1196
+ urlMap[enc] = url;
1197
+ }
1198
+ let scopeApplied = false;
1199
+ const nodesForOutline = yield (() => __async(null, null, function* () {
1200
+ var _a5, _b2, _c;
1201
+ const sel = (_a5 = opts.focusSelector) == null ? void 0 : _a5.trim();
1202
+ if (!sel) return nodes;
1203
+ try {
1204
+ const looksLikeXPath = /^xpath=/i.test(sel) || sel.startsWith("/");
1205
+ const objectId = looksLikeXPath ? yield resolveObjectIdForXPath(session, sel, frameId) : yield resolveObjectIdForCss(session, sel, frameId);
1206
+ if (!objectId) return nodes;
1207
+ const desc = yield session.send(
1208
+ "DOM.describeNode",
1209
+ { objectId }
1210
+ );
1211
+ const be = (_b2 = desc.node) == null ? void 0 : _b2.backendNodeId;
1212
+ if (typeof be !== "number") return nodes;
1213
+ const target = nodes.find((n) => n.backendDOMNodeId === be);
1214
+ if (!target) return nodes;
1215
+ scopeApplied = true;
1216
+ const keep = /* @__PURE__ */ new Set([target.nodeId]);
1217
+ const queue = [target];
1218
+ while (queue.length) {
1219
+ const cur = queue.shift();
1220
+ for (const id of (_c = cur.childIds) != null ? _c : []) {
1221
+ if (keep.has(id)) continue;
1222
+ keep.add(id);
1223
+ const child = nodes.find((n) => n.nodeId === id);
1224
+ if (child) queue.push(child);
1225
+ }
1226
+ }
1227
+ return nodes.filter((n) => keep.has(n.nodeId)).map(
1228
+ (n) => n.nodeId === target.nodeId ? __spreadProps(__spreadValues({}, n), { parentId: void 0 }) : n
1229
+ );
1230
+ } catch (e2) {
1231
+ return nodes;
1232
+ }
1233
+ }))();
1234
+ const decorated = decorateRoles(nodesForOutline, opts);
1235
+ const { tree } = yield buildHierarchicalTree(decorated, opts);
1236
+ const simplified = tree.map((n) => formatTreeLine(n)).join("\n");
1237
+ return { outline: simplified.trimEnd(), urlMap, scopeApplied };
1238
+ });
1239
+ }
1240
+ function decorateRoles(nodes, opts) {
1241
+ const asRole = (n) => {
1242
+ var _a4, _b;
1243
+ return String((_b = (_a4 = n.role) == null ? void 0 : _a4.value) != null ? _b : "");
1244
+ };
1245
+ return nodes.map((n) => {
1246
+ var _a4, _b, _c;
1247
+ let encodedId;
1248
+ if (typeof n.backendDOMNodeId === "number") {
1249
+ try {
1250
+ encodedId = opts.encode(n.backendDOMNodeId);
1251
+ } catch (e2) {
1252
+ }
1253
+ }
1254
+ let role = asRole(n);
1255
+ const domIsScrollable = encodedId ? opts.scrollableMap[encodedId] === true : false;
1256
+ const tag = encodedId ? opts.tagNameMap[encodedId] : void 0;
1257
+ const isHtmlElement = tag === "html";
1258
+ if ((domIsScrollable || isHtmlElement) && tag !== "#document") {
1259
+ const tagLabel = tag && tag.startsWith("#") ? tag.slice(1) : tag;
1260
+ role = tagLabel ? `scrollable, ${tagLabel}` : `scrollable${role ? `, ${role}` : ""}`;
1261
+ }
1262
+ return {
1263
+ role,
1264
+ name: (_a4 = n.name) == null ? void 0 : _a4.value,
1265
+ description: (_b = n.description) == null ? void 0 : _b.value,
1266
+ value: (_c = n.value) == null ? void 0 : _c.value,
1267
+ nodeId: n.nodeId,
1268
+ backendDOMNodeId: n.backendDOMNodeId,
1269
+ parentId: n.parentId,
1270
+ childIds: n.childIds,
1271
+ encodedId
1272
+ };
1273
+ });
1274
+ }
1275
+ function buildHierarchicalTree(nodes, opts) {
1276
+ return __async(this, null, function* () {
1277
+ var _a4;
1278
+ const nodeMap = /* @__PURE__ */ new Map();
1279
+ for (const n of nodes) {
1280
+ const keep = !!(n.name && n.name.trim()) || !!(n.childIds && n.childIds.length) || !isStructural(n.role);
1281
+ if (!keep) continue;
1282
+ nodeMap.set(n.nodeId, __spreadValues({}, n));
1283
+ }
1284
+ for (const n of nodes) {
1285
+ if (!n.parentId) continue;
1286
+ const parent = nodeMap.get(n.parentId);
1287
+ const cur = nodeMap.get(n.nodeId);
1288
+ if (parent && cur) ((_a4 = parent.children) != null ? _a4 : parent.children = []).push(cur);
1289
+ }
1290
+ const roots = nodes.filter((n) => !n.parentId && nodeMap.has(n.nodeId)).map((n) => nodeMap.get(n.nodeId));
1291
+ const cleaned = (yield Promise.all(roots.map(pruneStructuralSafe))).filter(
1292
+ Boolean
1293
+ );
1294
+ return { tree: cleaned };
1295
+ function pruneStructuralSafe(node) {
1296
+ return __async(this, null, function* () {
1297
+ var _a5;
1298
+ if (+node.nodeId < 0) return null;
1299
+ const children = (_a5 = node.children) != null ? _a5 : [];
1300
+ if (!children.length) {
1301
+ return isStructural(node.role) ? null : node;
1302
+ }
1303
+ const cleanedKids = (yield Promise.all(children.map(pruneStructuralSafe))).filter(Boolean);
1304
+ const prunedStatic = removeRedundantStaticTextChildren(node, cleanedKids);
1305
+ if (isStructural(node.role)) {
1306
+ if (prunedStatic.length === 1) return prunedStatic[0];
1307
+ if (prunedStatic.length === 0) return null;
1308
+ }
1309
+ let newRole = node.role;
1310
+ if ((newRole === "generic" || newRole === "none") && node.encodedId) {
1311
+ const tagName = opts.tagNameMap[node.encodedId];
1312
+ if (tagName) newRole = tagName;
1313
+ }
1314
+ if (newRole === "combobox" && node.encodedId) {
1315
+ const tagName = opts.tagNameMap[node.encodedId];
1316
+ if (tagName === "select") newRole = "select";
1317
+ }
1318
+ return __spreadProps(__spreadValues({}, node), { role: newRole, children: prunedStatic });
1319
+ });
1320
+ }
1321
+ });
1322
+ }
1323
+ function isStructural(role) {
1324
+ const r2 = role == null ? void 0 : role.toLowerCase();
1325
+ return r2 === "generic" || r2 === "none" || r2 === "inlinetextbox";
1326
+ }
1327
+ function extractUrlFromAXNode(ax) {
1328
+ var _a4, _b;
1329
+ const props = (_a4 = ax.properties) != null ? _a4 : [];
1330
+ const urlProp = props.find((p) => p.name === "url");
1331
+ const value = (_b = urlProp == null ? void 0 : urlProp.value) == null ? void 0 : _b.value;
1332
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
1333
+ }
1334
+ function removeRedundantStaticTextChildren(parent, children) {
1335
+ if (!parent.name) return children;
1336
+ const parentNorm = normaliseSpaces(parent.name).trim();
1337
+ let combined = "";
1338
+ for (const c of children) {
1339
+ if (c.role === "StaticText" && c.name) {
1340
+ combined += normaliseSpaces(c.name).trim();
1341
+ }
1342
+ }
1343
+ if (combined === parentNorm) {
1344
+ return children.filter((c) => c.role !== "StaticText");
1345
+ }
1346
+ return children;
1347
+ }
1348
+ var init_a11yTree = __esm({
1349
+ "lib/v3/understudy/a11y/snapshot/a11yTree.ts"() {
1350
+ init_focusSelectors();
1351
+ init_treeFormatUtils();
1352
+ }
1353
+ });
1354
+
1355
+ // lib/v3/understudy/a11y/snapshot/domTree.ts
1356
+ function isCborStackError(message) {
1357
+ return message.includes("CBOR: stack limit exceeded");
1358
+ }
1359
+ function shouldExpandNode(node) {
1360
+ var _a4, _b, _c;
1361
+ const declaredChildren = (_a4 = node.childNodeCount) != null ? _a4 : 0;
1362
+ const realizedChildren = (_c = (_b = node.children) == null ? void 0 : _b.length) != null ? _c : 0;
1363
+ return declaredChildren > realizedChildren;
1364
+ }
1365
+ function mergeDomNodes(target, source) {
1366
+ var _a4, _b, _c, _d2;
1367
+ target.childNodeCount = (_a4 = source.childNodeCount) != null ? _a4 : target.childNodeCount;
1368
+ target.children = (_b = source.children) != null ? _b : target.children;
1369
+ target.shadowRoots = (_c = source.shadowRoots) != null ? _c : target.shadowRoots;
1370
+ target.contentDocument = (_d2 = source.contentDocument) != null ? _d2 : target.contentDocument;
1371
+ }
1372
+ function collectDomTraversalTargets(node) {
1373
+ const targets = [];
1374
+ if (node.children) targets.push(...node.children);
1375
+ if (node.shadowRoots) targets.push(...node.shadowRoots);
1376
+ if (node.contentDocument) targets.push(node.contentDocument);
1377
+ return targets;
1378
+ }
1379
+ function hydrateDomTree(session, root, pierce) {
1380
+ return __async(this, null, function* () {
1381
+ var _a4, _b;
1382
+ const stack = [root];
1383
+ const expandedNodeIds = /* @__PURE__ */ new Set();
1384
+ const expandedBackendIds = /* @__PURE__ */ new Set();
1385
+ while (stack.length) {
1386
+ const node = stack.pop();
1387
+ const nodeId = typeof node.nodeId === "number" && node.nodeId > 0 ? node.nodeId : void 0;
1388
+ const backendId = typeof node.backendNodeId === "number" && node.backendNodeId > 0 ? node.backendNodeId : void 0;
1389
+ const seenByNode = nodeId ? expandedNodeIds.has(nodeId) : false;
1390
+ const seenByBackend = !nodeId && backendId ? expandedBackendIds.has(backendId) : false;
1391
+ if (seenByNode || seenByBackend) continue;
1392
+ if (nodeId) expandedNodeIds.add(nodeId);
1393
+ else if (backendId) expandedBackendIds.add(backendId);
1394
+ const needsExpansion = shouldExpandNode(node);
1395
+ if (needsExpansion && (nodeId || backendId)) {
1396
+ const describeParamsBase = nodeId ? { nodeId } : { backendNodeId: backendId };
1397
+ let expanded = false;
1398
+ for (const depth of DESCRIBE_DEPTH_ATTEMPTS) {
1399
+ try {
1400
+ const described = yield session.send(
1401
+ "DOM.describeNode",
1402
+ __spreadProps(__spreadValues({}, describeParamsBase), {
1403
+ depth,
1404
+ pierce
1405
+ })
1406
+ );
1407
+ mergeDomNodes(node, described.node);
1408
+ if (!nodeId && described.node.nodeId && described.node.nodeId > 0) {
1409
+ node.nodeId = described.node.nodeId;
1410
+ expandedNodeIds.add(described.node.nodeId);
1411
+ }
1412
+ expanded = true;
1413
+ break;
1414
+ } catch (err) {
1415
+ const message = err instanceof Error ? err.message : String(err);
1416
+ if (isCborStackError(message)) {
1417
+ continue;
1418
+ }
1419
+ const identifier = (_a4 = nodeId != null ? nodeId : backendId) != null ? _a4 : "unknown";
1420
+ throw new StagehandDomProcessError(
1421
+ `Failed to expand DOM node ${identifier}: ${String(err)}`
1422
+ );
1423
+ }
1424
+ }
1425
+ if (!expanded) {
1426
+ const identifier = (_b = nodeId != null ? nodeId : backendId) != null ? _b : "unknown";
1427
+ throw new StagehandDomProcessError(
1428
+ `Unable to expand DOM node ${identifier} after describeNode depth retries`
1429
+ );
1430
+ }
1431
+ }
1432
+ for (const child of collectDomTraversalTargets(node)) {
1433
+ stack.push(child);
1434
+ }
1435
+ }
1436
+ });
1437
+ }
1438
+ function getDomTreeWithFallback(session, pierce) {
1439
+ return __async(this, null, function* () {
1440
+ let lastCborMessage = "";
1441
+ for (const depth of DOM_DEPTH_ATTEMPTS) {
1442
+ try {
1443
+ const { root } = yield session.send(
1444
+ "DOM.getDocument",
1445
+ { depth, pierce }
1446
+ );
1447
+ if (depth !== -1) {
1448
+ yield hydrateDomTree(session, root, pierce);
1449
+ }
1450
+ return root;
1451
+ } catch (err) {
1452
+ const message = err instanceof Error ? err.message : String(err);
1453
+ if (isCborStackError(message)) {
1454
+ lastCborMessage = message;
1455
+ continue;
1456
+ }
1457
+ throw err;
1458
+ }
1459
+ }
1460
+ throw new StagehandDomProcessError(
1461
+ lastCborMessage ? `CDP DOM.getDocument failed after adaptive depth retries: ${lastCborMessage}` : "CDP DOM.getDocument failed after adaptive depth retries."
1462
+ );
1463
+ });
1464
+ }
1465
+ function domMapsForSession(session, frameId, pierce, encode, attemptOwnerLookup = true) {
1466
+ return __async(this, null, function* () {
1467
+ var _a4, _b;
1468
+ yield session.send("DOM.enable").catch(() => {
1469
+ });
1470
+ const root = yield getDomTreeWithFallback(session, pierce);
1471
+ let startNode = root;
1472
+ if (attemptOwnerLookup) {
1473
+ try {
1474
+ const owner = yield session.send(
1475
+ "DOM.getFrameOwner",
1476
+ { frameId }
1477
+ );
1478
+ const ownerBackendId = owner.backendNodeId;
1479
+ if (typeof ownerBackendId === "number") {
1480
+ const ownerEl = findNodeByBackendId(root, ownerBackendId);
1481
+ if (ownerEl == null ? void 0 : ownerEl.contentDocument) {
1482
+ startNode = ownerEl.contentDocument;
1483
+ }
1484
+ }
1485
+ } catch (e2) {
1486
+ }
1487
+ }
1488
+ const tagNameMap = {};
1489
+ const xpathMap = {};
1490
+ const scrollableMap = {};
1491
+ const stack = [{ node: startNode, xpath: "" }];
1492
+ while (stack.length) {
1493
+ const { node, xpath } = stack.pop();
1494
+ if (node.backendNodeId) {
1495
+ const encId = encode(frameId, node.backendNodeId);
1496
+ tagNameMap[encId] = String(node.nodeName).toLowerCase();
1497
+ xpathMap[encId] = xpath || "/";
1498
+ const isScrollable = (node == null ? void 0 : node.isScrollable) === true;
1499
+ if (isScrollable) scrollableMap[encId] = true;
1500
+ }
1501
+ const kids = (_a4 = node.children) != null ? _a4 : [];
1502
+ if (kids.length) {
1503
+ const segs = buildChildXPathSegments(kids);
1504
+ for (let i2 = kids.length - 1; i2 >= 0; i2--) {
1505
+ const child = kids[i2];
1506
+ const step = segs[i2];
1507
+ stack.push({
1508
+ node: child,
1509
+ xpath: joinXPath(xpath, step)
1510
+ });
1511
+ }
1512
+ }
1513
+ for (const sr of (_b = node.shadowRoots) != null ? _b : []) {
1514
+ stack.push({
1515
+ node: sr,
1516
+ xpath: joinXPath(xpath, "//")
1517
+ });
1518
+ }
1519
+ }
1520
+ return { tagNameMap, xpathMap, scrollableMap };
1521
+ });
1522
+ }
1523
+ function buildSessionDomIndex(session, pierce) {
1524
+ return __async(this, null, function* () {
1525
+ var _a4, _b;
1526
+ yield session.send("DOM.enable").catch(() => {
1527
+ });
1528
+ const root = yield getDomTreeWithFallback(session, pierce);
1529
+ const absByBe = /* @__PURE__ */ new Map();
1530
+ const tagByBe = /* @__PURE__ */ new Map();
1531
+ const scrollByBe = /* @__PURE__ */ new Map();
1532
+ const docRootOf = /* @__PURE__ */ new Map();
1533
+ const contentDocRootByIframe = /* @__PURE__ */ new Map();
1534
+ const rootBe = root.backendNodeId;
1535
+ const stack = [{ node: root, xp: "/", docRootBe: rootBe }];
1536
+ while (stack.length) {
1537
+ const { node, xp, docRootBe } = stack.pop();
1538
+ if (node.backendNodeId) {
1539
+ absByBe.set(node.backendNodeId, xp || "/");
1540
+ tagByBe.set(node.backendNodeId, String(node.nodeName).toLowerCase());
1541
+ if ((node == null ? void 0 : node.isScrollable) === true) scrollByBe.set(node.backendNodeId, true);
1542
+ docRootOf.set(node.backendNodeId, docRootBe);
1543
+ }
1544
+ const kids = (_a4 = node.children) != null ? _a4 : [];
1545
+ if (kids.length) {
1546
+ const segs = buildChildXPathSegments(kids);
1547
+ for (let i2 = kids.length - 1; i2 >= 0; i2--) {
1548
+ const child = kids[i2];
1549
+ const step = segs[i2];
1550
+ stack.push({ node: child, xp: joinXPath(xp, step), docRootBe });
1551
+ }
1552
+ }
1553
+ for (const sr of (_b = node.shadowRoots) != null ? _b : []) {
1554
+ stack.push({ node: sr, xp: joinXPath(xp, "//"), docRootBe });
1555
+ }
1556
+ const cd = node.contentDocument;
1557
+ if (cd && typeof cd.backendNodeId === "number") {
1558
+ contentDocRootByIframe.set(node.backendNodeId, cd.backendNodeId);
1559
+ stack.push({ node: cd, xp, docRootBe: cd.backendNodeId });
1560
+ }
1561
+ }
1562
+ return {
1563
+ rootBackend: rootBe,
1564
+ absByBe,
1565
+ tagByBe,
1566
+ scrollByBe,
1567
+ docRootOf,
1568
+ contentDocRootByIframe
1569
+ };
1570
+ });
1571
+ }
1572
+ function relativizeXPath(baseAbs, nodeAbs) {
1573
+ const base = normalizeXPath(baseAbs);
1574
+ const abs = normalizeXPath(nodeAbs);
1575
+ if (abs === base) return "/";
1576
+ if (abs.startsWith(base)) {
1577
+ const tail = abs.slice(base.length);
1578
+ if (!tail) return "/";
1579
+ return tail.startsWith("/") || tail.startsWith("//") ? tail : `/${tail}`;
1580
+ }
1581
+ if (base === "/") return abs;
1582
+ return abs;
1583
+ }
1584
+ function findNodeByBackendId(root, backendNodeId) {
1585
+ const stack = [root];
1586
+ while (stack.length) {
1587
+ const n = stack.pop();
1588
+ if (n.backendNodeId === backendNodeId) return n;
1589
+ if (n.children) for (const c of n.children) stack.push(c);
1590
+ if (n.shadowRoots) for (const s2 of n.shadowRoots) stack.push(s2);
1591
+ }
1592
+ return void 0;
1593
+ }
1594
+ var DOM_DEPTH_ATTEMPTS, DESCRIBE_DEPTH_ATTEMPTS;
1595
+ var init_domTree = __esm({
1596
+ "lib/v3/understudy/a11y/snapshot/domTree.ts"() {
1597
+ init_sdkErrors();
1598
+ init_xpathUtils();
1599
+ DOM_DEPTH_ATTEMPTS = [-1, 256, 128, 64, 32, 16, 8, 4, 2, 1];
1600
+ DESCRIBE_DEPTH_ATTEMPTS = [-1, 64, 32, 16, 8, 4, 2, 1];
1601
+ }
1602
+ });
1603
+
1604
+ // lib/v3/understudy/a11y/snapshot/sessions.ts
1605
+ function ownerSession(page, frameId) {
1606
+ return page.getSessionForFrame(frameId);
1607
+ }
1608
+ function parentSession(page, parentByFrame, frameId) {
1609
+ var _a4;
1610
+ const parentId = (_a4 = parentByFrame.get(frameId)) != null ? _a4 : null;
1611
+ if (!parentId) {
1612
+ return page.getSessionForFrame(frameId);
1613
+ }
1614
+ return page.getSessionForFrame(parentId);
1615
+ }
1616
+ var init_sessions = __esm({
1617
+ "lib/v3/understudy/a11y/snapshot/sessions.ts"() {
1618
+ }
1619
+ });
1620
+
1621
+ // lib/v3/understudy/a11y/snapshot/capture.ts
1622
+ function captureHybridSnapshot(page, options) {
1623
+ return __async(this, null, function* () {
1624
+ var _a4;
1625
+ const pierce = (_a4 = options == null ? void 0 : options.pierceShadow) != null ? _a4 : true;
1626
+ const context = buildFrameContext(page);
1627
+ const scopedSnapshot = yield tryScopedSnapshot(
1628
+ page,
1629
+ options,
1630
+ context,
1631
+ pierce
1632
+ );
1633
+ if (scopedSnapshot) return scopedSnapshot;
1634
+ const sessionToIndex = yield buildSessionIndexes(
1635
+ page,
1636
+ context.frames,
1637
+ pierce
1638
+ );
1639
+ const { perFrameMaps, perFrameOutlines } = yield collectPerFrameMaps(
1640
+ page,
1641
+ context,
1642
+ sessionToIndex,
1643
+ options,
1644
+ pierce
1645
+ );
1646
+ const { absPrefix, iframeHostEncByChild } = yield computeFramePrefixes(
1647
+ page,
1648
+ context,
1649
+ perFrameMaps
1650
+ );
1651
+ return mergeFramesIntoSnapshot(
1652
+ context,
1653
+ perFrameMaps,
1654
+ perFrameOutlines,
1655
+ absPrefix,
1656
+ iframeHostEncByChild
1657
+ );
1658
+ });
1659
+ }
1660
+ function buildFrameContext(page) {
1661
+ const rootId = page.mainFrameId();
1662
+ const frameTree = page.asProtocolFrameTree(rootId);
1663
+ const parentByFrame = /* @__PURE__ */ new Map();
1664
+ (function index(n, parent) {
1665
+ var _a4;
1666
+ parentByFrame.set(n.frame.id, parent);
1667
+ for (const c of (_a4 = n.childFrames) != null ? _a4 : []) index(c, n.frame.id);
1668
+ })(frameTree, null);
1669
+ const frames = page.listAllFrameIds();
1670
+ return { rootId, parentByFrame, frames };
1671
+ }
1672
+ function tryScopedSnapshot(page, options, context, pierce) {
1673
+ return __async(this, null, function* () {
1674
+ var _a4, _b;
1675
+ const requestedFocus = (_a4 = options == null ? void 0 : options.focusSelector) == null ? void 0 : _a4.trim();
1676
+ if (!requestedFocus) return null;
1677
+ const logScopeFallback = () => {
1678
+ var _a5;
1679
+ v3Logger({
1680
+ message: `Unable to narrow scope with selector. Falling back to using full DOM`,
1681
+ level: 1,
1682
+ auxiliary: {
1683
+ arguments: {
1684
+ value: `selector: ${(_a5 = options == null ? void 0 : options.focusSelector) == null ? void 0 : _a5.trim()}`,
1685
+ type: "string"
1686
+ }
1687
+ }
1688
+ });
1689
+ };
1690
+ try {
1691
+ let targetFrameId;
1692
+ let tailSelector;
1693
+ let absPrefix;
1694
+ const looksLikeXPath = /^xpath=/i.test(requestedFocus) || requestedFocus.startsWith("/");
1695
+ if (looksLikeXPath) {
1696
+ const focus = normalizeXPath(requestedFocus);
1697
+ const hit = yield resolveFocusFrameAndTail(
1698
+ page,
1699
+ focus,
1700
+ context.parentByFrame,
1701
+ context.rootId
1702
+ );
1703
+ targetFrameId = hit.targetFrameId;
1704
+ tailSelector = hit.tailXPath || void 0;
1705
+ absPrefix = hit.absPrefix;
1706
+ } else {
1707
+ const cssHit = yield resolveCssFocusFrameAndTail(
1708
+ page,
1709
+ requestedFocus,
1710
+ context.parentByFrame,
1711
+ context.rootId
1712
+ );
1713
+ targetFrameId = cssHit.targetFrameId;
1714
+ tailSelector = cssHit.tailSelector || void 0;
1715
+ absPrefix = cssHit.absPrefix;
1716
+ }
1717
+ const owningSess = ownerSession(page, targetFrameId);
1718
+ const parentId = context.parentByFrame.get(targetFrameId);
1719
+ const sameSessionAsParent = !!parentId && ownerSession(page, parentId) === ownerSession(page, targetFrameId);
1720
+ const { tagNameMap, xpathMap, scrollableMap } = yield domMapsForSession(
1721
+ owningSess,
1722
+ targetFrameId,
1723
+ pierce,
1724
+ (fid, be) => `${page.getOrdinal(fid)}-${be}`,
1725
+ sameSessionAsParent
1726
+ );
1727
+ const { outline, urlMap, scopeApplied } = yield a11yForFrame(
1728
+ owningSess,
1729
+ targetFrameId,
1730
+ {
1731
+ focusSelector: tailSelector || void 0,
1732
+ tagNameMap,
1733
+ experimental: (_b = options == null ? void 0 : options.experimental) != null ? _b : false,
1734
+ scrollableMap,
1735
+ encode: (backendNodeId) => `${page.getOrdinal(targetFrameId)}-${backendNodeId}`
1736
+ }
1737
+ );
1738
+ const scopedXpathMap = {};
1739
+ const abs = absPrefix != null ? absPrefix : "";
1740
+ const isRoot = !abs || abs === "/";
1741
+ if (isRoot) {
1742
+ Object.assign(scopedXpathMap, xpathMap);
1743
+ } else {
1744
+ for (const [encId, xp] of Object.entries(xpathMap)) {
1745
+ scopedXpathMap[encId] = prefixXPath(abs, xp);
1746
+ }
1747
+ }
1748
+ const scopedUrlMap = __spreadValues({}, urlMap);
1749
+ const snapshot = {
1750
+ combinedTree: outline,
1751
+ combinedXpathMap: scopedXpathMap,
1752
+ combinedUrlMap: scopedUrlMap,
1753
+ perFrame: [
1754
+ {
1755
+ frameId: targetFrameId,
1756
+ outline,
1757
+ xpathMap,
1758
+ urlMap
1759
+ }
1760
+ ]
1761
+ };
1762
+ if (scopeApplied) {
1763
+ return snapshot;
1764
+ }
1765
+ logScopeFallback();
1766
+ } catch (e2) {
1767
+ logScopeFallback();
1768
+ }
1769
+ return null;
1770
+ });
1771
+ }
1772
+ function buildSessionIndexes(page, frames, pierce) {
1773
+ return __async(this, null, function* () {
1774
+ var _a4;
1775
+ const sessionToIndex = /* @__PURE__ */ new Map();
1776
+ const sessionById = /* @__PURE__ */ new Map();
1777
+ for (const frameId of frames) {
1778
+ const sess = ownerSession(page, frameId);
1779
+ const sid = (_a4 = sess.id) != null ? _a4 : "root";
1780
+ if (!sessionById.has(sid)) sessionById.set(sid, sess);
1781
+ }
1782
+ for (const [sid, sess] of sessionById.entries()) {
1783
+ const idx = yield buildSessionDomIndex(sess, pierce);
1784
+ sessionToIndex.set(sid, idx);
1785
+ }
1786
+ return sessionToIndex;
1787
+ });
1788
+ }
1789
+ function collectPerFrameMaps(page, context, sessionToIndex, options, pierce) {
1790
+ return __async(this, null, function* () {
1791
+ var _a4, _b, _c;
1792
+ const perFrameMaps = /* @__PURE__ */ new Map();
1793
+ const perFrameOutlines = [];
1794
+ for (const frameId of context.frames) {
1795
+ const sess = ownerSession(page, frameId);
1796
+ const sid = (_a4 = sess.id) != null ? _a4 : "root";
1797
+ let idx = sessionToIndex.get(sid);
1798
+ if (!idx) {
1799
+ idx = yield buildSessionDomIndex(sess, pierce);
1800
+ sessionToIndex.set(sid, idx);
1801
+ }
1802
+ const parentId = context.parentByFrame.get(frameId);
1803
+ const sameSessionAsParent = !!parentId && ownerSession(page, parentId) === sess;
1804
+ let docRootBe = idx.rootBackend;
1805
+ if (sameSessionAsParent) {
1806
+ try {
1807
+ const { backendNodeId } = yield sess.send(
1808
+ "DOM.getFrameOwner",
1809
+ { frameId }
1810
+ );
1811
+ if (typeof backendNodeId === "number") {
1812
+ const cdBe = idx.contentDocRootByIframe.get(backendNodeId);
1813
+ if (typeof cdBe === "number") docRootBe = cdBe;
1814
+ }
1815
+ } catch (e2) {
1816
+ }
1817
+ }
1818
+ const tagNameMap = {};
1819
+ const xpathMap = {};
1820
+ const scrollableMap = {};
1821
+ const enc = (be) => `${page.getOrdinal(frameId)}-${be}`;
1822
+ const baseAbs = (_b = idx.absByBe.get(docRootBe)) != null ? _b : "/";
1823
+ for (const [be, nodeAbs] of idx.absByBe.entries()) {
1824
+ const nodeDocRoot = idx.docRootOf.get(be);
1825
+ if (nodeDocRoot !== docRootBe) continue;
1826
+ const rel = relativizeXPath(baseAbs, nodeAbs);
1827
+ const key = enc(be);
1828
+ xpathMap[key] = rel;
1829
+ const tag = idx.tagByBe.get(be);
1830
+ if (tag) tagNameMap[key] = tag;
1831
+ if (idx.scrollByBe.get(be)) scrollableMap[key] = true;
1832
+ }
1833
+ const { outline, urlMap } = yield a11yForFrame(sess, frameId, {
1834
+ experimental: (_c = options == null ? void 0 : options.experimental) != null ? _c : false,
1835
+ tagNameMap,
1836
+ scrollableMap,
1837
+ encode: (backendNodeId) => `${page.getOrdinal(frameId)}-${backendNodeId}`
1838
+ });
1839
+ perFrameOutlines.push({ frameId, outline });
1840
+ perFrameMaps.set(frameId, { tagNameMap, xpathMap, scrollableMap, urlMap });
1841
+ }
1842
+ return { perFrameMaps, perFrameOutlines };
1843
+ });
1844
+ }
1845
+ function computeFramePrefixes(page, context, perFrameMaps) {
1846
+ return __async(this, null, function* () {
1847
+ const absPrefix = /* @__PURE__ */ new Map();
1848
+ const iframeHostEncByChild = /* @__PURE__ */ new Map();
1849
+ absPrefix.set(context.rootId, "");
1850
+ const queue = [context.rootId];
1851
+ while (queue.length) {
1852
+ const parent = queue.shift();
1853
+ const parentAbs = absPrefix.get(parent);
1854
+ for (const child of context.frames) {
1855
+ if (context.parentByFrame.get(child) !== parent) continue;
1856
+ queue.push(child);
1857
+ const parentSess = parentSession(page, context.parentByFrame, child);
1858
+ const ownerBackendNodeId = yield (() => __async(null, null, function* () {
1859
+ try {
1860
+ const { backendNodeId } = yield parentSess.send("DOM.getFrameOwner", { frameId: child });
1861
+ return backendNodeId;
1862
+ } catch (e2) {
1863
+ return void 0;
1864
+ }
1865
+ }))();
1866
+ if (!ownerBackendNodeId) {
1867
+ absPrefix.set(child, parentAbs);
1868
+ continue;
1869
+ }
1870
+ const parentDom = perFrameMaps.get(parent);
1871
+ const iframeEnc = `${page.getOrdinal(parent)}-${ownerBackendNodeId}`;
1872
+ const iframeXPath = parentDom == null ? void 0 : parentDom.xpathMap[iframeEnc];
1873
+ const childAbs = iframeXPath ? prefixXPath(parentAbs || "/", iframeXPath) : parentAbs;
1874
+ absPrefix.set(child, childAbs);
1875
+ iframeHostEncByChild.set(child, iframeEnc);
1876
+ }
1877
+ }
1878
+ return { absPrefix, iframeHostEncByChild };
1879
+ });
1880
+ }
1881
+ function mergeFramesIntoSnapshot(context, perFrameMaps, perFrameOutlines, absPrefix, iframeHostEncByChild) {
1882
+ var _a4, _b, _c, _d2, _e;
1883
+ const combinedXpathMap = {};
1884
+ const combinedUrlMap = {};
1885
+ for (const frameId of context.frames) {
1886
+ const maps = perFrameMaps.get(frameId);
1887
+ if (!maps) continue;
1888
+ const abs = (_a4 = absPrefix.get(frameId)) != null ? _a4 : "";
1889
+ const isRoot = abs === "" || abs === "/";
1890
+ if (isRoot) {
1891
+ Object.assign(combinedXpathMap, maps.xpathMap);
1892
+ Object.assign(combinedUrlMap, maps.urlMap);
1893
+ continue;
1894
+ }
1895
+ for (const [encId, xp] of Object.entries(maps.xpathMap)) {
1896
+ combinedXpathMap[encId] = prefixXPath(abs, xp);
1897
+ }
1898
+ Object.assign(combinedUrlMap, maps.urlMap);
1899
+ }
1900
+ const idToTree = /* @__PURE__ */ new Map();
1901
+ for (const { frameId, outline } of perFrameOutlines) {
1902
+ const parentEnc = iframeHostEncByChild.get(frameId);
1903
+ if (parentEnc) idToTree.set(parentEnc, outline);
1904
+ }
1905
+ const rootOutline = (_e = (_d2 = (_b = perFrameOutlines.find((o) => o.frameId === context.rootId)) == null ? void 0 : _b.outline) != null ? _d2 : (_c = perFrameOutlines[0]) == null ? void 0 : _c.outline) != null ? _e : "";
1906
+ const combinedTree = injectSubtrees(rootOutline, idToTree);
1907
+ return {
1908
+ combinedTree,
1909
+ combinedXpathMap,
1910
+ combinedUrlMap,
1911
+ perFrame: perFrameOutlines.map(({ frameId, outline }) => {
1912
+ var _a5, _b2;
1913
+ const maps = perFrameMaps.get(frameId);
1914
+ return {
1915
+ frameId,
1916
+ outline,
1917
+ xpathMap: (_a5 = maps == null ? void 0 : maps.xpathMap) != null ? _a5 : {},
1918
+ urlMap: (_b2 = maps == null ? void 0 : maps.urlMap) != null ? _b2 : {}
1919
+ };
1920
+ })
1921
+ };
1922
+ }
1923
+ var init_capture = __esm({
1924
+ "lib/v3/understudy/a11y/snapshot/capture.ts"() {
1925
+ init_logger();
1926
+ init_a11yTree();
1927
+ init_focusSelectors();
1928
+ init_domTree();
1929
+ init_treeFormatUtils();
1930
+ init_sessions();
1931
+ init_xpathUtils();
1932
+ }
1933
+ });
1934
+
1935
+ // lib/v3/understudy/a11yInvocation.ts
1936
+ function buildA11yInvocation(name, args) {
1937
+ const invocation = `${a11yScriptGlobalRefs[name]}(${args.join(", ")})`;
1938
+ return `(() => { ${a11yScriptBootstrap}; return ${invocation}; })()`;
1939
+ }
1940
+ var init_a11yInvocation = __esm({
1941
+ "lib/v3/understudy/a11yInvocation.ts"() {
1942
+ init_a11yScripts_generated();
1943
+ }
1944
+ });
1945
+
1946
+ // lib/v3/understudy/a11y/snapshot/activeElement.ts
1947
+ function computeActiveElementXpath(page) {
1948
+ return __async(this, null, function* () {
1949
+ var _a4;
1950
+ const tree = page.getFullFrameTree();
1951
+ const parentByFrame = /* @__PURE__ */ new Map();
1952
+ (function index(n, parent) {
1953
+ var _a5;
1954
+ parentByFrame.set(n.frame.id, parent);
1955
+ for (const c of (_a5 = n.childFrames) != null ? _a5 : []) index(c, n.frame.id);
1956
+ })(tree, null);
1957
+ const frames = page.listAllFrameIds();
1958
+ let focusedFrameId = null;
1959
+ for (const fid of frames) {
1960
+ const sess = page.getSessionForFrame(fid);
1961
+ try {
1962
+ yield sess.send("Runtime.enable").catch(() => {
1963
+ });
1964
+ const ctxId = yield executionContexts.waitForMainWorld(sess, fid, 1e3).catch(() => {
1965
+ });
1966
+ const hasFocusExpr = buildA11yInvocation("documentHasFocusStrict", []);
1967
+ const evalParams = ctxId ? {
1968
+ contextId: ctxId,
1969
+ expression: hasFocusExpr,
1970
+ returnByValue: true
1971
+ } : { expression: hasFocusExpr, returnByValue: true };
1972
+ const { result } = yield sess.send(
1973
+ "Runtime.evaluate",
1974
+ evalParams
1975
+ );
1976
+ if ((result == null ? void 0 : result.value) === true) {
1977
+ focusedFrameId = fid;
1978
+ break;
1979
+ }
1980
+ } catch (e2) {
1981
+ }
1982
+ }
1983
+ if (!focusedFrameId) focusedFrameId = page.mainFrameId();
1984
+ const focusedSession = page.getSessionForFrame(focusedFrameId);
1985
+ let objectId;
1986
+ try {
1987
+ yield focusedSession.send("Runtime.enable").catch(() => {
1988
+ });
1989
+ const ctxId = yield executionContexts.waitForMainWorld(focusedSession, focusedFrameId, 1e3).catch(() => {
1990
+ });
1991
+ const activeExpr = buildA11yInvocation("resolveDeepActiveElement", []);
1992
+ const evalParams = ctxId ? {
1993
+ contextId: ctxId,
1994
+ expression: activeExpr,
1995
+ returnByValue: false
1996
+ } : { expression: activeExpr, returnByValue: false };
1997
+ const { result } = yield focusedSession.send(
1998
+ "Runtime.evaluate",
1999
+ evalParams
2000
+ );
2001
+ objectId = result == null ? void 0 : result.objectId;
2002
+ } catch (e2) {
2003
+ objectId = void 0;
2004
+ }
2005
+ if (!objectId) return null;
2006
+ const leafXPath = yield (() => __async(null, null, function* () {
2007
+ try {
2008
+ const { result } = yield focusedSession.send("Runtime.callFunctionOn", {
2009
+ objectId,
2010
+ functionDeclaration: a11yScriptSources.nodeToAbsoluteXPath,
2011
+ returnByValue: true
2012
+ });
2013
+ try {
2014
+ yield focusedSession.send("Runtime.releaseObject", { objectId });
2015
+ } catch (e2) {
2016
+ }
2017
+ const xp = (result == null ? void 0 : result.value) || "";
2018
+ return typeof xp === "string" && xp ? xp : null;
2019
+ } catch (e2) {
2020
+ try {
2021
+ yield focusedSession.send("Runtime.releaseObject", { objectId });
2022
+ } catch (e3) {
2023
+ }
2024
+ return null;
2025
+ }
2026
+ }))();
2027
+ if (!leafXPath) return null;
2028
+ let prefix = "";
2029
+ let cur = focusedFrameId;
2030
+ while (cur) {
2031
+ const parent = (_a4 = parentByFrame.get(cur)) != null ? _a4 : null;
2032
+ if (!parent) break;
2033
+ const parentSess = page.getSessionForFrame(parent);
2034
+ try {
2035
+ const { backendNodeId } = yield parentSess.send("DOM.getFrameOwner", { frameId: cur });
2036
+ if (typeof backendNodeId === "number") {
2037
+ const xp = yield absoluteXPathForBackendNode(parentSess, backendNodeId);
2038
+ if (xp) prefix = prefix ? prefixXPath(prefix, xp) : normalizeXPath(xp);
2039
+ }
2040
+ } catch (e2) {
2041
+ }
2042
+ cur = parent;
2043
+ }
2044
+ return prefix ? prefixXPath(prefix, leafXPath) : normalizeXPath(leafXPath);
2045
+ });
2046
+ }
2047
+ var init_activeElement = __esm({
2048
+ "lib/v3/understudy/a11y/snapshot/activeElement.ts"() {
2049
+ init_executionContextRegistry();
2050
+ init_a11yInvocation();
2051
+ init_a11yScripts_generated();
2052
+ init_xpathUtils();
2053
+ }
2054
+ });
2055
+
2056
+ // lib/v3/understudy/a11y/snapshot/coordinateResolver.ts
2057
+ function resolveXpathForLocation(page, x2, y) {
2058
+ return __async(this, null, function* () {
2059
+ var _a4, _b, _c, _d2, _e, _f, _g, _h;
2060
+ const tree = page.getFullFrameTree();
2061
+ const parentByFrame = /* @__PURE__ */ new Map();
2062
+ (function index(n, parent) {
2063
+ var _a5;
2064
+ parentByFrame.set(n.frame.id, parent);
2065
+ for (const c of (_a5 = n.childFrames) != null ? _a5 : []) index(c, n.frame.id);
2066
+ })(tree, null);
2067
+ const iframeChain = [];
2068
+ let curFrameId = page.mainFrameId();
2069
+ let curSession = page.getSessionForFrame(curFrameId);
2070
+ let curX = x2;
2071
+ let curY = y;
2072
+ for (let depth = 0; depth < 8; depth++) {
2073
+ try {
2074
+ yield curSession.send("DOM.enable").catch(() => {
2075
+ });
2076
+ let sx = 0;
2077
+ let sy = 0;
2078
+ try {
2079
+ yield curSession.send("Runtime.enable").catch(() => {
2080
+ });
2081
+ const ctxId = yield executionContexts.waitForMainWorld(curSession, curFrameId).catch(() => {
2082
+ });
2083
+ const scrollExpr = buildA11yInvocation("getScrollOffsets", []);
2084
+ const evalParams = ctxId ? {
2085
+ contextId: ctxId,
2086
+ expression: scrollExpr,
2087
+ returnByValue: true
2088
+ } : { expression: scrollExpr, returnByValue: true };
2089
+ const { result } = yield curSession.send("Runtime.evaluate", evalParams);
2090
+ sx = Number((_b = (_a4 = result == null ? void 0 : result.value) == null ? void 0 : _a4.sx) != null ? _b : 0);
2091
+ sy = Number((_d2 = (_c = result == null ? void 0 : result.value) == null ? void 0 : _c.sy) != null ? _d2 : 0);
2092
+ } catch (e2) {
2093
+ }
2094
+ const xi = Math.max(0, Math.floor(curX + sx));
2095
+ const yi = Math.max(0, Math.floor(curY + sy));
2096
+ let res;
2097
+ try {
2098
+ res = yield curSession.send("DOM.getNodeForLocation", {
2099
+ x: xi,
2100
+ y: yi,
2101
+ includeUserAgentShadowDOM: false,
2102
+ ignorePointerEventsNone: false
2103
+ });
2104
+ } catch (e2) {
2105
+ return null;
2106
+ }
2107
+ const be = res == null ? void 0 : res.backendNodeId;
2108
+ const reportedFrameId = res == null ? void 0 : res.frameId;
2109
+ if (typeof be === "number" && reportedFrameId && reportedFrameId !== curFrameId) {
2110
+ const abs = yield buildAbsoluteXPathFromChain(
2111
+ iframeChain,
2112
+ curSession,
2113
+ be
2114
+ );
2115
+ return abs ? { frameId: reportedFrameId, backendNodeId: be, absoluteXPath: abs } : null;
2116
+ }
2117
+ if (typeof be !== "number") return null;
2118
+ let matchedChild;
2119
+ for (const fid of listChildrenOf(parentByFrame, curFrameId)) {
2120
+ try {
2121
+ const { backendNodeId } = yield curSession.send("DOM.getFrameOwner", { frameId: fid });
2122
+ if (backendNodeId === be) {
2123
+ matchedChild = fid;
2124
+ break;
2125
+ }
2126
+ } catch (e2) {
2127
+ continue;
2128
+ }
2129
+ }
2130
+ if (!matchedChild) {
2131
+ const abs = yield buildAbsoluteXPathFromChain(
2132
+ iframeChain,
2133
+ curSession,
2134
+ be
2135
+ );
2136
+ return abs ? { frameId: curFrameId, backendNodeId: be, absoluteXPath: abs } : null;
2137
+ }
2138
+ iframeChain.push({
2139
+ parentSession: curSession,
2140
+ iframeBackendNodeId: be
2141
+ });
2142
+ let left = 0;
2143
+ let top = 0;
2144
+ try {
2145
+ const { object } = yield curSession.send("DOM.resolveNode", { backendNodeId: be });
2146
+ const objectId = object == null ? void 0 : object.objectId;
2147
+ if (objectId) {
2148
+ const { result } = yield curSession.send("Runtime.callFunctionOn", {
2149
+ objectId,
2150
+ functionDeclaration: a11yScriptSources.getBoundingRectLite,
2151
+ returnByValue: true
2152
+ });
2153
+ left = Number((_f = (_e = result == null ? void 0 : result.value) == null ? void 0 : _e.left) != null ? _f : 0);
2154
+ top = Number((_h = (_g = result == null ? void 0 : result.value) == null ? void 0 : _g.top) != null ? _h : 0);
2155
+ yield curSession.send("Runtime.releaseObject", { objectId }).catch(() => {
2156
+ });
2157
+ }
2158
+ } catch (e2) {
2159
+ }
2160
+ curX = Math.max(0, curX - left);
2161
+ curY = Math.max(0, curY - top);
2162
+ curFrameId = matchedChild;
2163
+ curSession = page.getSessionForFrame(curFrameId);
2164
+ } catch (e2) {
2165
+ return null;
2166
+ }
2167
+ }
2168
+ return null;
2169
+ });
2170
+ }
2171
+ var init_coordinateResolver = __esm({
2172
+ "lib/v3/understudy/a11y/snapshot/coordinateResolver.ts"() {
2173
+ init_executionContextRegistry();
2174
+ init_a11yScripts_generated();
2175
+ init_a11yInvocation();
2176
+ init_focusSelectors();
2177
+ init_xpathUtils();
2178
+ }
2179
+ });
2180
+
2181
+ // lib/v3/understudy/a11y/snapshot/index.ts
2182
+ var init_snapshot = __esm({
2183
+ "lib/v3/understudy/a11y/snapshot/index.ts"() {
2184
+ init_capture();
2185
+ init_activeElement();
2186
+ init_treeFormatUtils();
2187
+ init_coordinateResolver();
2050
2188
  }
2051
2189
  });
2052
2190