UNPKG

@react-native/debugger-frontend

Version:
2 lines (1 loc) • 23 kB
import*as e from"../../../core/common/common.js";import*as t from"../../../core/i18n/i18n.js";import*as r from"../../../third_party/puppeteer-replay/puppeteer-replay.js";import{AssertedEventType as s,SelectorType as n,StepType as i}from"../../../third_party/puppeteer-replay/puppeteer-replay.js";import*as a from"../../../ui/legacy/legacy.js";import*as o from"../../../core/sdk/sdk.js";import*as c from"../../../services/puppeteer/puppeteer.js";import*as d from"../../../core/platform/platform.js";import*as l from"../util/util.js";var g=Object.freeze({__proto__:null}),p=Object.freeze({__proto__:null,AssertedEventType:s,SelectorType:n,StepType:i});const h={defaultRecordingName:"Recording {DATE} at {TIME}"},u=t.i18n.registerUIStrings("panels/recorder/models/RecorderSettings.ts",h),m=t.i18n.getLocalizedString.bind(void 0,u);var f=Object.freeze({__proto__:null,RecorderSettings:class{#e=e.Settings.Settings.instance().createSetting("recorder-selector-attribute","");#t=e.Settings.Settings.instance().createSetting("recorder-panel-replay-speed","normal");#r=e.Settings.Settings.instance().createSetting("recorder-panel-replay-extension","");#s=new Map;#n=e.Settings.Settings.instance().createSetting("recorder-preferred-copy-format","json");constructor(){for(const t of Object.values(n))this.#s.set(t,e.Settings.Settings.instance().createSetting(`recorder-${t}-selector-enabled`,!0))}get selectorAttribute(){return this.#e.get()}set selectorAttribute(e){this.#e.set(e)}get speed(){return this.#t.get()}set speed(e){this.#t.set(e)}get replayExtension(){return this.#r.get()}set replayExtension(e){this.#r.set(e)}get defaultTitle(){const e=new Date;return m(h.defaultRecordingName,{DATE:e.toLocaleDateString(),TIME:e.toLocaleTimeString()})}get defaultSelectors(){return Object.values(n).filter((e=>this.getSelectorByType(e)))}getSelectorByType(e){return this.#s.get(e)?.get()}setSelectorByType(e,t){this.#s.get(e)?.set(t)}get preferredCopyFormat(){return this.#n.get()}set preferredCopyFormat(e){this.#n.set(e)}}});var y=Object.freeze({__proto__:null,RecorderShortcutHelper:class{#i;#a=null;#o;constructor(e=200){this.#o=e,this.#i=new AbortController}#c(){this.#i.abort(),this.#a&&clearTimeout(this.#a),this.#i=new AbortController}#d(e){this.#c(),e()}handleShortcut(e){this.#c(),document.addEventListener("keyup",(t=>{a.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(t)&&this.#d(e)}),{signal:this.#i.signal}),this.#a=setTimeout((()=>this.#d(e)),this.#o)}}});const w={normal:0,slow:500,very_slow:1e3,extremely_slow:2e3};function v(t){return e.ParsedURL.schemeIs(t.url,"devtools:")||"page"===t.type||"background_page"===t.type||"webview"===t.type}class T extends e.ObjectWrapper.ObjectWrapper{userFlow;speed;timeout;breakpointIndexes;steppingOver=!1;aborted=!1;#l=Promise.withResolvers();#g=Promise.withResolvers();#p;constructor(e,{speed:t,breakpointIndexes:r=new Set}){super(),this.userFlow=e,this.speed=t,this.timeout=e.timeout||5e3,this.breakpointIndexes=r}#h(){this.#l.resolve(),this.#l=Promise.withResolvers()}static async connectPuppeteer(){const e=o.TargetManager.TargetManager.instance().rootTarget();if(!e)throw new Error("Could not find the root target");const t=o.TargetManager.TargetManager.instance().primaryPageTarget();if(!t)throw new Error("Could not find the primary page target");const r=t.model(o.ChildTargetManager.ChildTargetManager);if(!r)throw new Error("Could not get childTargetManager");const s=t.model(o.ResourceTreeModel.ResourceTreeModel);if(!s)throw new Error("Could not get resource tree model");if(!s.mainFrame)throw new Error("Could not find main frame");const n=e.model(o.ChildTargetManager.ChildTargetManager);if(!n)throw new Error("Could not find the child target manager class for the root target");const i=(await n.createParallelConnection((()=>{}))).connection,a=await r.getParentTargetId(),d=await n.getParentTargetId(),{page:l,browser:g,puppeteerConnection:p}=await c.PuppeteerConnection.PuppeteerConnectionHelper.connectPuppeteerToConnectionViaTab({connection:i,rootTargetId:d,isPageTargetCallback:v});if(!l)throw new Error("could not find main page!");return g.on("targetdiscovered",(e=>{"page"===e.type&&e.targetId!==a&&e.openerId===a&&p._createSession(e,!0)})),{page:l,browser:g}}static async disconnectPuppeteer(e){try{const t=await e.pages();for(const e of t){const t=e._client();await t.send("Network.disable"),await t.send("Page.disable"),await t.send("Log.disable"),await t.send("Performance.disable"),await t.send("Runtime.disable"),await t.send("Emulation.clearDeviceMetricsOverride"),await t.send("Emulation.setAutomationOverride",{enabled:!1});for(const t of e.frames()){const e=t.client;await e.send("Network.disable"),await e.send("Page.disable"),await e.send("Log.disable"),await e.send("Performance.disable"),await e.send("Runtime.disable"),await e.send("Emulation.setAutomationOverride",{enabled:!1})}}await e.disconnect()}catch(e){console.error("Error disconnecting Puppeteer",e.message)}}async stop(){await Promise.race([this.#l,this.#g])}get abortPromise(){return this.#g.promise}abort(){this.aborted=!0,this.#g.resolve(),this.#p?.abort()}disposeForTesting(){this.#l.resolve(),this.#g.resolve()}continue(){this.steppingOver=!1,this.#h()}stepOver(){this.steppingOver=!0,this.#h()}updateBreakpointIndexes(e){this.breakpointIndexes=e}async play(){const{page:t,browser:s}=await T.connectPuppeteer();this.aborted=!1;const n=this;class i extends r.PuppeteerRunnerExtension{#t;constructor(e,t,{timeout:r,speed:s}){super(e,t,{timeout:r}),this.#t=s}async beforeEachStep(e,t){const{resolve:r,promise:s}=Promise.withResolvers();n.dispatchEventToListeners("Step",{step:e,resolve:r}),await s;const i=t.steps.indexOf(e),a=n.steppingOver||n.breakpointIndexes.has(i),o="setViewport"!==e.type&&"navigate"!==e.type&&!n.aborted;a?(n.dispatchEventToListeners("Stop"),await n.stop(),n.dispatchEventToListeners("Continue")):o&&await Promise.race([new Promise((e=>setTimeout(e,w[this.#t]))),n.abortPromise])}async runStep(r,s){if(!e.ParsedURL.schemeIs(t?.url(),"devtools:")||"setViewport"!==r.type&&"navigate"!==r.type){if("navigate"===r.type&&e.ParsedURL.schemeIs(r.url,"chrome:"))throw new Error("Not allowed to replay on chrome:// URLs");await this.page.bringToFront(),await super.runStep(r,s)}}}const a=new i(s,t,{timeout:this.timeout,speed:this.speed});let o;this.#p=await r.createRunner(this.userFlow,a);try{await this.#p.run()}catch(e){o=e,console.error("Replay error",e.message)}finally{await T.disconnectPuppeteer(s)}this.aborted?this.dispatchEventToListeners("Abort"):o?this.dispatchEventToListeners("Error",o):this.dispatchEventToListeners("Done")}}var S=Object.freeze({__proto__:null,RecordingPlayer:T,defaultTimeout:5e3});function b(e){return{type:i.SetViewport,width:e.clientWidth,height:e.clientHeight,deviceScaleFactor:1,isMobile:!1,hasTouch:!1,isLandscape:!1}}function E(e){return{type:i.EmulateNetworkConditions,download:e.download,upload:e.upload,latency:e.latency}}function C(e,t){return"selectors"in e&&"selectors"in t?JSON.stringify(e.selectors)===JSON.stringify(t.selectors):!("selectors"in e)&&!("selectors"in t)}const R=r.parse,M=r.parseStep;var k=Object.freeze({__proto__:null,areSelectorsEqual:C,createEmulateNetworkConditionsStep:E,createViewportStep:b,maxTimeout:3e4,minTimeout:1,parse:R,parseStep:M});function A(e){return o.TargetManager.TargetManager.instance().primaryPageTarget()===e||"main"===e.id()?"main":e.inspectedURL()}function _(e,t){const r=[];for(;t;){const e=t.sameTargetParentFrame();if(!e)break;const s=e.childFrames.indexOf(t);r.unshift(s),t=e}return{target:A(e),frame:r}}async function N(e,t,r){const s=t.model(o.RuntimeModel.RuntimeModel).executionContexts(),n=t.model(o.ResourceTreeModel.ResourceTreeModel);for(const i of n.frames()){if(!s.find((e=>e.frameId===i.id)))continue;const{executionContextId:n}=await t.pageAgent().invoke_createIsolatedWorld({frameId:i.id,worldName:e});await t.runtimeAgent().invoke_evaluate({expression:r,includeCommandLineAPI:!0,contextId:n})}}var I=Object.freeze({__proto__:null,evaluateInAllFrames:N,findFrameIdByExecutionContext:function(e,t){for(const r of e){const e=r.model(o.RuntimeModel.RuntimeModel);if(e)for(const r of e.executionContexts())if(r.id===t&&void 0!==r.frameId)return r.frameId}},findTargetByExecutionContext:function(e,t){for(const r of e){const e=r.model(o.RuntimeModel.RuntimeModel);if(e)for(const s of e.executionContexts())if(s.id===t)return r}},getTargetFrameContext:_,getTargetName:A,isFrameTargetInfo:e=>"page"===e.type||"iframe"===e.type});const P=d.StringUtilities.formatAsJSLiteral,x=new Set(["typed","address_bar","auto_bookmark","auto_subframe","generated","auto_toplevel","reload","keyword","keyword_generated"]),O=Object.freeze({addStep:"addStep",stopShortcut:"stopShortcut"});class F extends e.ObjectWrapper.ObjectWrapper{#u;#m;#f;#y;#w;#v=new Map;#T=new Map;#S=new Map;#b=new Map;#E=new Map;#C=new Map;#R=new e.Mutex.Mutex;#M;#k=new Map;#A=!1;#_=[];constructor(e,t){super(),this.#u=e,this.#m=e.pageAgent(),this.#f=e.targetAgent(),this.#y=o.NetworkManager.MultitargetNetworkManager.instance();const r=e.model(o.ResourceTreeModel.ResourceTreeModel);if(!r)throw new Error("ResourceTreeModel is missing for the target: "+e.id());this.#w=r,this.#u=e,this.#M={title:t.title,selectorAttribute:t.selectorAttribute,steps:[]},this.#_=t.selectorTypesToRecord}cloneUserFlow(){return structuredClone(this.#M)}overwriteUserFlow(e){this.#M=structuredClone(e)}async start(){if(this.#A)throw new Error("The session has started");this.#A=!0,this.#y.addEventListener("ConditionsChanged",this.#N,this),await this.#I(),await this.#m.invoke_bringToFront(),await this.#P(this.#u)}async stop(){await this.#x(),this.#R.acquire(),await Promise.all([...this.#v.values()].map(this.#O)),this.#y.removeEventListener("ConditionsChanged",this.#N,this)}async#I(){const e=this.#w.mainFrame;if(!e)throw new Error("Could not find mainFrame.");this.#y.networkConditions()!==o.NetworkManager.NoThrottlingConditions&&this.#N();const{cssLayoutViewport:t}=await this.#u.pageAgent().invoke_getLayoutMetrics();this.#F(b(t));const r=await this.#w.navigationHistory();if(r){const e=r.entries[r.currentIndex];this.#T.set(this.#u.id(),e.id),this.#S.set(this.#u.id(),r.entries.map((e=>e.id))),this.#M.steps.push({type:i.Navigate,url:e.url,assertedEvents:[{type:s.Navigation,url:e.url,title:e.title}]})}else this.#M.steps.push({type:i.Navigate,url:e.url,assertedEvents:[{type:s.Navigation,url:e.url,title:await this.#L(this.#u)}]});this.#x()}async#L(e){const t=await e.runtimeAgent().invoke_evaluate({expression:"document.title"});return t.result?.value||""}#N(){const e=this.#y.networkConditions();this.#F(E(e))}#D;#B=[];#x(){return this.#D&&clearTimeout(this.#D),this.#D=setTimeout((()=>{this.dispatchEventToListeners("recordingupdated",structuredClone(this.#M)),this.#D=void 0;for(const e of this.#B)e();this.#B.length=0}),100),new Promise((e=>{this.#B.push(e)}))}get#U(){return this.#M.steps.slice(-1)[0]}#j=new Set;#F(e){switch(e.type){case"doubleClick":for(let t=this.#M.steps.length-1;t>0;t--){const r=this.#M.steps[t];if("click"===r.type){e.selectors=r.selectors,this.#M.steps.splice(t,1);break}}break;case"change":{const t=this.#U;if(!t)break;switch(t.type){case"change":if(!C(e,t))break;return this.#M.steps[this.#M.steps.length-1]=e,void this.#x();case"keyDown":return this.#j.add(t.key),this.#M.steps.pop(),void this.#F(e)}break}case"keyDown":if(this.#j.has(e.key))return;break;case"keyUp":if(this.#j.has(e.key))return void this.#j.delete(e.key)}this.#M.steps.push(e),this.#x()}#z(e,t){const r=this.#M.steps[this.#M.steps.length-1];if(r&&!r.assertedEvents?.find((e=>e.type===s.Navigation))){const n=e.target||"main",i=(e.frame||[]).join(","),a=r.target||"main",o=(("frame"in r?r.frame:[])||[]).join(",");n===a&&i===o&&(r.assertedEvents=[{type:s.Navigation}],this.#k.set(t.id(),r),this.#x())}}#W(e,t){const r=this.#k.get(e.id());if(!r)return;const n=r;if(!n.assertedEvents)return;const i=n.assertedEvents.find((e=>e.type===s.Navigation));i&&!i.url&&(i.url=t.url,i.title=t.title,this.#x())}#K(e){const t=Number(e.data.payload);for(let e=0;e<t-1;e++)this.#M.steps.pop();this.dispatchEventToListeners("recordingstopped",structuredClone(this.#M))}#H(e,t){switch(t.data.name){case O.stopShortcut:return void this.#K(t);case O.addStep:return void this.#$(e,t);default:return}}#$(e,t){const r=t.data.executionContextId;let s;const n=e.model(o.RuntimeModel.RuntimeModel);if(n)for(const e of n.executionContexts())if(e.id===r){s=e.frameId;break}if(!s)throw new Error("No execution context found for the binding call + "+JSON.stringify(t.data));const i=JSON.parse(t.data.payload),a=e.model(o.ResourceTreeModel.ResourceTreeModel).frameForId(s);if(!a)throw new Error("Could not find frame.");const c=_(e,a);if("beforeUnload"!==i.type)switch(i.type){case"change":this.#F({type:"change",value:i.value,selectors:i.selectors,frame:c.frame.length?c.frame:void 0,target:c.target});break;case"doubleClick":this.#F({type:"doubleClick",target:c.target,selectors:i.selectors,offsetY:i.offsetY,offsetX:i.offsetX,frame:c.frame.length?c.frame:void 0,deviceType:i.deviceType,button:i.button});break;case"click":this.#F({type:"click",target:c.target,selectors:i.selectors,offsetY:i.offsetY,offsetX:i.offsetX,frame:c.frame.length?c.frame:void 0,duration:i.duration,deviceType:i.deviceType,button:i.button});break;case"keyUp":this.#F({type:"keyUp",key:i.key,frame:c.frame.length?c.frame:void 0,target:c.target});break;case"keyDown":this.#F({type:"keyDown",frame:c.frame.length?c.frame:void 0,target:c.target,key:i.key});break;default:throw new Error("Unhandled client event")}else this.#z(c,e)}#V(){return(e=>{const t=[];for(const r of e)for(const e of r){const r={meta:!1,ctrl:!1,shift:!1,alt:!1,keyCode:-1},{keyCode:s,modifiers:n}=a.KeyboardShortcut.KeyboardShortcut.keyCodeAndModifiersFromKey(e);r.keyCode=s;const i=a.KeyboardShortcut.Modifiers;r.ctrl=Boolean(n&i.Ctrl.value),r.meta=Boolean(n&i.Meta.value),r.shift=Boolean(n&i.Shift.value),r.shift=Boolean(n&i.Alt.value),-1!==r.keyCode&&t.push(r)}return t})(a.ShortcutRegistry.ShortcutRegistry.instance().shortcutsForAction("chrome-recorder.start-recording").map((e=>e.descriptors.map((e=>e.key)))))}static get#G(){try{return e.Settings.Settings.instance().settingForTest("untrusted-recorder-events"),!0}catch{}return!1}#P=async e=>{if(e.type()!==o.Target.Type.FRAME)return;this.#v.set(e.id(),e);const t=e.model(o.AccessibilityModel.AccessibilityModel);d.assertNotNullOrUndefined(t),await t.resumeModel(),await this.#J(e),await this.#q(e);const r=e.model(o.ChildTargetManager.ChildTargetManager);d.assertNotNullOrUndefined(r),this.#C.set(e,[r.addEventListener("TargetCreated",this.#X.bind(this,e)),r.addEventListener("TargetDestroyed",this.#Y.bind(this,e)),r.addEventListener("TargetInfoChanged",this.#Q.bind(this,e))]),await Promise.all(r.childTargets().map(this.#P))};#O=async t=>{const r=this.#C.get(t);r&&e.EventTarget.removeEventListeners(r),await this.#Z(t),await this.#ee(t)};async#J(e){const t=e.model(o.RuntimeModel.RuntimeModel);d.assertNotNullOrUndefined(t),this.#E.set(e,[t.addEventListener(o.RuntimeModel.Events.BindingCalled,this.#H.bind(this,e))]),await Promise.all(Object.values(O).map((e=>t.addBinding({name:e,executionContextName:l.DEVTOOLS_RECORDER_WORLD_NAME}))))}async#ee(t){await Promise.all(Object.values(O).map((e=>t.runtimeAgent().invoke_removeBinding({name:e}))));const r=this.#E.get(t);r&&e.EventTarget.removeEventListeners(r)}async#q(e){const t=`\n ${await l.InjectedScript.get()};DevToolsRecorder.startRecording({getAccessibleName, getAccessibleRole}, {\n debug: ${l.isDebugBuild},\n allowUntrustedEvents: ${F.#G},\n selectorTypesToRecord: ${JSON.stringify(this.#_)},\n selectorAttribute: ${this.#M.selectorAttribute?P(this.#M.selectorAttribute):void 0},\n stopShortcuts: ${JSON.stringify(this.#V())},\n });\n `,[{identifier:r}]=await Promise.all([e.pageAgent().invoke_addScriptToEvaluateOnNewDocument({source:t,worldName:l.DEVTOOLS_RECORDER_WORLD_NAME,includeCommandLineAPI:!0}),N(l.DEVTOOLS_RECORDER_WORLD_NAME,e,t)]);this.#b.set(e.id(),r)}async#Z(e){const t=this.#b.get(e.id());t&&(await e.pageAgent().invoke_removeScriptToEvaluateOnNewDocument({identifier:t}),await(async(e,t,r)=>{await Promise.all(t.map((t=>N(e,t,r))))})(l.DEVTOOLS_RECORDER_WORLD_NAME,[...this.#v.values()],"DevToolsRecorder.stopRecording()"))}#X(e,t){this.#te({type:"targetCreated",event:t,target:e})}#Y(e,t){const r=this.#v.get(t.data);r&&this.#te({type:"targetClosed",event:t,target:r})}#Q(e,t){const r=this.#v.get(t.data.targetId)||e;this.#te({type:"targetInfoChanged",event:t,target:r})}#te(e){return this.#R.run((async()=>{try{switch(l.isDebugBuild&&console.time(`Processing ${JSON.stringify(e)}`),e.type){case"targetClosed":await this.#re(e);break;case"targetCreated":await this.#se(e);break;case"targetInfoChanged":await this.#ne(e)}l.isDebugBuild&&console.timeEnd(`Processing ${JSON.stringify(e)}`)}catch(e){console.error("Error happened while processing recording events: ",e.message,e.stack)}}))}async#se(e){if("page"!==e.event.data.type&&"iframe"!==e.event.data.type)return;await this.#f.invoke_attachToTarget({targetId:e.event.data.targetId,flatten:!0});const t=o.TargetManager.TargetManager.instance().targets().find((t=>t.id()===e.event.data.targetId));if(!t)throw new Error("Could not find target.");await this.#P(t),window.dispatchEvent(new Event("recorderAttachedToTarget"))}async#re(e){const t=this.#k.get(e.target.id());t&&(delete t.assertedEvents,this.#k.delete(e.target.id()))}async#ie(e,t){const r=await e.navigationHistory();if(!r)return!1;const n=r.entries[r.currentIndex];if(this.#T.get(t.id())===n.id)return!0;this.#T.set(t.id(),n.id);const a=this.#S.get(t.id())||[];if(this.#S.set(t.id(),r.entries.map((e=>e.id))),x.has(n.transitionType)||a.includes(n.id)){const e=this.#k.get(t.id());e&&(delete e.assertedEvents,this.#k.delete(t.id())),this.#F({type:i.Navigate,url:n.url,assertedEvents:[{type:s.Navigation,url:n.url,title:n.title}]})}else this.#W(t,{type:s.Navigation,url:n.url,title:n.title});return!0}async#ne(e){if("page"!==e.event.data.type&&"iframe"!==e.event.data.type)return;const t=e.target,r=t.model(o.ResourceTreeModel.ResourceTreeModel);if(!r)throw new Error("ResourceTreeModel is missing in handleNavigation");if("iframe"===e.event.data.type)this.#W(t,{type:s.Navigation,url:e.event.data.url,title:await this.#L(t)});else if("page"===e.event.data.type){if(await this.#ie(r,t))return;await this.#ae(r,500),this.#W(t,{type:s.Navigation,url:e.event.data.url,title:await this.#L(t)})}}async#ae(e,t){const{resolve:r,promise:s}=Promise.withResolvers(),n=()=>{e.removeEventListener(o.ResourceTreeModel.Events.DOMContentLoaded,n),r()};e.addEventListener(o.ResourceTreeModel.Events.DOMContentLoaded,n),await Promise.any([s,new Promise((r=>setTimeout((()=>{e.removeEventListener(o.ResourceTreeModel.Events.DOMContentLoaded,n),r()}),t)))])}}var L=Object.freeze({__proto__:null,RecordingSession:F}),D=Object.freeze({__proto__:null});let B=null;class U{next(){return crypto.randomUUID()}}class j{#oe;#R=new e.Mutex.Mutex;#ce=new U;constructor(){this.#oe=e.Settings.Settings.instance().createSetting("recorder-recordings-ng",[])}clearForTest(){this.#oe.set([]),this.#ce=new U}setIdGeneratorForTest(e){this.#ce=e}async saveRecording(e){const t=await this.#R.acquire();try{const t=await this.#oe.forceGet(),r={storageName:this.#ce.next(),flow:e};return t.push(r),this.#oe.set(t),r}finally{t()}}async updateRecording(e,t){const r=await this.#R.acquire();try{const r=await this.#oe.forceGet(),s=r.find((t=>t.storageName===e));if(!s)throw new Error("No recording is found during updateRecording");return s.flow=t,this.#oe.set(r),s}finally{r()}}async deleteRecording(e){const t=await this.#R.acquire();try{const t=await this.#oe.forceGet();this.#oe.set(t.filter((t=>t.storageName!==e)))}finally{t()}}getRecording(e){return this.#oe.get().find((t=>t.storageName===e))}getRecordings(){return this.#oe.get()}static instance(){return B||(B=new j),B}}var z=Object.freeze({__proto__:null,RecordingStorage:j});let W=null;const K=52428800;class H{#de;#le;#ge;constructor(t=52428800){this.#de=e.Settings.Settings.instance().createSetting("recorder-screenshots",[]),this.#le=this.#pe(),this.#ge=t}clear(){this.#de.set([]),this.#le=new Map}getScreenshotForSection(e,t){const r=this.#le.get(this.#he(e,t));return r?(this.#ue(r),r.data):null}storeScreenshotForSection(e,t,r){const s={recordingName:e,index:t,data:r};this.#le.set(this.#he(e,t),s),this.#ue(s)}deleteScreenshotsForRecording(e){for(const[t,r]of this.#le)r.recordingName===e&&this.#le.delete(t);this.#ue()}#he(e,t){return`${e}:${t}`}#pe(){const e=new Map,t=this.#de.get();for(const r of t)e.set(this.#he(r.recordingName,r.index),r);return e}#ue(e){if(e){const t=this.#he(e.recordingName,e.index);this.#le.delete(t),this.#le.set(t,e)}const t=[];let r=0;for(const[e,s]of Array.from(this.#le.entries()).reverse())r<this.#ge?(r+=s.data.length,t.push(s)):this.#le.delete(e);this.#de.set(t.reverse())}static instance(e={forceNew:null,maxStorageSize:K}){const{forceNew:t,maxStorageSize:r}=e;return W&&!t||(W=new H(r)),W}}var $=Object.freeze({__proto__:null,ScreenshotStorage:H});async function V(e){const t=new Image,r=new Promise((e=>{t.onload=e}));t.src=e,await r;const s=document.createElement("canvas"),n=s.getContext("2d");if(!n)throw new Error("Could not create context.");const i=t.width/t.height;s.width=160,s.height=Math.min(240,160/i);const a=await createImageBitmap(t,{resizeWidth:160,resizeQuality:"high"});return n.drawImage(a,0,0),s.toDataURL("image/png")}var G=Object.freeze({__proto__:null,resizeScreenshot:V,takeScreenshot:async function(){const e=await async function(){const e=o.TargetManager.TargetManager.instance().primaryPageTarget();if(!e)throw new Error("Could not find main target");const{data:t}=await e.pageAgent().invoke_captureScreenshot({});return t?"data:image/png;base64,"+t:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"}();return await V(e)}});function J(e){const t=e.assertedEvents?.find((e=>"navigation"===e.type));return"navigate"===e.type?{title:t?.title||"",url:e.url,steps:[],causingStep:e}:t?{title:t.title||"",url:t.url||"",steps:[]}:null}var q=Object.freeze({__proto__:null,buildSections:function(e){let t=null;const r=[];for(const s of e){if(t)t.steps.push(s);else{if("navigate"===s.type){t=J(s);continue}t={title:"Current page",url:"",steps:[s]}}const e=J(s);e&&(t&&r.push(t),t=e)}return!t||r.length&&!t.steps.length||r.push(t),r}});var X=Object.freeze({__proto__:null,getTooltipForActions:function(e,t){let r=e;const s=a.ShortcutRegistry.ShortcutRegistry.instance().shortcutsForAction(t);for(const e of s)r+=` - ${e.title()}`;return r}});export{g as ConverterIds,f as RecorderSettings,y as RecorderShortcutHelper,S as RecordingPlayer,L as RecordingSession,D as RecordingSettings,z as RecordingStorage,I as SDKUtils,p as Schema,k as SchemaUtils,$ as ScreenshotStorage,G as ScreenshotUtils,q as Section,X as Tooltip};