import{readFileSync as W,existsSync as F,readdirSync as O}from"node:fs";import{join as N}from"node:path";import{execSync as L}from"node:child_process";import{tmpdir as B}from"node:os";var v=class{static async parseTraceZip(h){let o;if(h.endsWith(".zip")&&F(h)){let n=N(B(),`trace-${Date.now()}`);L(`unzip -q "${h}" -d "${n}"`,{stdio:"pipe"});let a=O(n).find(c=>c.endsWith(".trace"));if(!a)throw new Error("No .trace file found in zip");o=N(n,a)}else if(F(h)){let u=O(h).find(a=>a.endsWith(".trace"));if(!u)throw new Error("No .trace file found");o=N(h,u)}else throw new Error(`Trace not found at ${h}`);try{let u=W(o,"utf-8").trim().split(`
`),a=[],c=new Map,r=new Map;for(let w of u)try{let t=JSON.parse(w);if(t.type==="snapshot"&&t.snapshot&&t.snapshot.accessibility){let l=new Map;for(let i of t.snapshot.accessibility)i.ref&&l.set(i.ref,i);c.set(t.snapshotName,l)}if(t.type==="frame-snapshot"&&t.snapshot){let l=Buffer.from(t.snapshot.html||"","base64").toString("utf-8");l&&l.length>100&&r.set(t.pageId||"default",l)}}catch{}for(let w of u)try{let t=JSON.parse(w);if(t.type==="before"&&t.params&&t.params.selector){let l=t.method;if(["click","fill","type","selectOption"].includes(l)){let i=t.params.selector,z=t.params.text||t.params.value||"",e=[],p=null,f=null,m=null,R=i.match(/aria-ref=([a-z0-9]+)/i);if(R&&t.snapshotName){let s=R[1],x=c.get(t.snapshotName);if(x&&x.has(s)){let y=x.get(s);p=y.name||null,f=y.role||null,m=y.label||null,console.log(`[TraceParser] \u2705 Found ACTUAL element data: text="${p}", role="${f}"`)}}let d=i.match(/internal:text="([^"]+)"/i),E=i.match(/internal:label="([^"]+)"/i),C=i.match(/internal:placeholder="([^"]+)"/i),T=i.match(/internal:role=([^ ]+)/i),M=i.match(/internal:describe="([^"]+)"/i),k=i.match(/name="([^"]+)"/i);if(d){e.push({type:"text",text:d[1]});let s=d[1].split(" ");s.length>1&&(e.push({type:"text",text:s[0],fuzzy:!0}),e.push({type:"text",text:s[s.length-1],fuzzy:!0}))}if(E&&e.push({type:"label",label:E[1]}),C&&e.push({type:"placeholder",placeholder:C[1]}),p){e.unshift({type:"text",text:p,source:"accessibility-tree"});let s=p.split(" ");s.length>1&&e.push({type:"text",text:s[0],fuzzy:!0,source:"accessibility-tree"})}if(f||T){let s=f||T[1],x=p||(k?k[1]:d?d[1]:null);e.unshift({type:"role",role:s,name:x,source:p?"accessibility-tree":"selector"})}if(m&&e.unshift({type:"label",label:m,source:"accessibility-tree"}),M){let s=M[1],x=["link","button","textbox","menuitem","submenu","combobox","checkbox","radio","tab","treeitem","menu item"],y=null,$=s;for(let g of x)if(s.toLowerCase().endsWith(` ${g}`)){y=g.replace(" ",""),$=s.substring(0,s.length-g.length-1);break}if(y){e.push({type:"role",role:y,name:$});let g=$.replace(/\s*\([^)]+\)\s*$/,"");e.push({type:"text",text:g}),e.push({type:"text",text:$});let S=$.split(" ");S.length>1&&(e.push({type:"text",text:S[0],fuzzy:!0}),e.push({type:"text",text:S.slice(0,2).join(" "),fuzzy:!0}))}else{let g=s.replace(/\s*\([^)]+\)\s*$/,"");e.push({type:"text",text:g}),e.push({type:"text",text:s})}}let A=this.extractDOMStrategies(i,r,d?.[1]||M?.[1],t.pageId);e.push(...A);let b=this.extractStructuralContext(i);(b.parent||b.sibling)&&e.forEach(s=>{["role","text","label","testid"].includes(s.type)&&(b.parent&&(s.parent=b.parent),b.sibling&&(s.sibling=b.sibling))}),e.push({type:"css",value:i});let j=p||d?d[1]:M?M[1].replace(/\s*\([^)]+\)\s*$/,""):`Action ${a.length}`;a.push({method:l,name:j,action:l==="type"?"fill":l,value:z,strategies:e,timestamp:t.startTime,actualText:p,actualRole:f,actualAriaLabel:m})}}}catch{}return a}catch(n){throw new Error(`Failed to parse trace: ${n.message}`,{cause:n})}}static extractDOMStrategies(h,o,n,u){let a=[];if(!o||o.size===0||!n)return a;try{let c=o.get(u);if(!c)return a;let r=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),w=new RegExp(`data-testid=["']([^"']+)["'][^>]*>[^<]*${r}`,"i"),t=c.match(w);t&&a.push({type:"testid",value:t[1],priority:"high"});let l=new RegExp(`class=["']([^"']+)["'][^>]*>[^<]*${r}`,"gi"),i=c.matchAll(l);for(let p of i){let f=p[1].split(/\s+/).filter(m=>m&&!m.match(/^(css|jss|makeStyles|MuiBox|MuiStack)-\w+/)&&m.length>2);f.length>0&&(a.push({type:"class",value:f.join("."),priority:"medium"}),f.length===1&&a.push({type:"class",value:f[0],priority:"medium"}))}let z=new RegExp(`id=["']([^"']+)["'][^>]*>[^<]*${r}`,"i"),e=c.match(z);e&&!e[1].match(/^(root|app|\d+|[a-f0-9-]{20,})$/i)&&a.push({type:"id",value:e[1],priority:"high"})}catch(c){console.warn(`[TraceParser] DOM extraction failed: ${c.message}`)}return a}static extractStructuralContext(h){let o={parent:null,sibling:null},n=h.split(">>").map(c=>c.trim());if(n.length>1){let r=n[n.length-2].replace(/internal:text="[^"]+"\s*/gi,"").replace(/internal:role=\S+\s*/gi,"").replace(/internal:label="[^"]+"\s*/gi,"").trim();r&&(r.match(/^(form|section|nav|header|aside|main|article)\b/)||r.includes("[")||r.match(/[#.]\w/))&&(o.parent=r)}let a=n[n.length-1].match(/([^+~]+)\s*[+~]\s*(.+)/);return a&&(o.sibling=a[1].trim()),o}},U=v;export{v as TraceParser,U as default};
