import{ar as F,aH as P,aY as f,az as z,aA as L,aT as s,q as U,c as y,ba as D,bb as O,o as I,u as B,w as M,b9 as x}from"./chunk-02oqS8tD.js";import{aY as _,aZ as b,W as V,aU as K,Z as W,S as H}from"./chunk-B8Q4vgLh.js";import{d as Y}from"./chunk-Cd_gpmCR.js";/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const q=F("ClipboardCheck",[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"m9 14 2 2 4-4",key:"df797q"}]]);function T(e,t,a){const r=e.snapshot?.url??"",n=e.kind==="responsive"?Z(t,a,r):e.kind==="accessibility"?G(a,r):J(t,r),d=X(a);return{title:A(e,r),description:se(e,n),steps:n,priority:d==="critical"?"Critical":d==="serious"?"High":"Medium",labels:[...new Set(["tcr-extension",e.kind])],runName:te(e,r),empty:n.length===0}}function Z(e,t,a){const r=w(t,"findings"),n=[];for(const d of e){if(d.type!=="VIEWPORT_CAPTURED"&&d.type!=="VIEWPORT_CAPTURE_FAILED")continue;const c=typeof d.meta?.viewportId=="string"?d.meta.viewportId:void 0,l=d.message.split("—")[0]?.split(":")[0]?.trim()??c??"viewport",i=d.message.includes("—")?d.message.split("—")[1]?.trim()??"":"";if(d.type==="VIEWPORT_CAPTURE_FAILED"){n.push({action:`Open the page at ${l} and capture it`,data:a,expectedResult:"The page renders at this size and can be captured.",actualResult:d.message,status:"Blocked"});continue}const h=c?r.filter(u=>u.affected.includes(c)):[],g=h.filter(u=>u.severity==="critical"||u.severity==="serious");n.push({action:`Open the page at ${l}${i?` (${i})`:""} and check the layout`,data:a,expectedResult:"The layout fits the viewport — no horizontal overflow, no clipped or overlapping content.",actualResult:h.length===0?"Nothing broke at this size.":h.map(u=>`${ee(u.severity)} ${u.title}`).join(`
`),status:g.length>0?"Failed":"Passed"})}return n}function G(e,t){const a=w(e,"findings"),r=new Map;for(const c of a){const l=r.get(c.ruleId)??[];l.push(c),r.set(c.ruleId,l)}const n=[...r.entries()].sort((c,l)=>$(c[1][0]?.severity)-$(l[1][0]?.severity)).map(([c,l])=>{const i=l[0],h=l.slice(0,10).map(u=>`· ${u.selectors[0]??u.html.slice(0,80)}`).join(`
`),g=l.length>10?`
· …and ${String(l.length-10)} more`:"";return{action:`Check: ${i?.title??c}`,data:t,expectedResult:i?.remediation??"The page satisfies this accessibility rule.",actualResult:`${String(l.length)} element${l.length===1?"":"s"} affected — ${i?.impact??""}
${h}${g}`,status:"Failed"}}),d=Q(e);for(const c of d)n.push({action:`Check: ${c.check}`,data:t,expectedResult:"The page satisfies this accessibility rule.",actualResult:c.reason,status:"Skipped"});return n}function J(e,t){return e.filter(a=>a.message.trim()!=="").slice(0,50).map(a=>({action:a.message,data:t,expectedResult:"The step completes without error.",actualResult:a.severity==="info"?"":a.message,status:a.severity==="error"?"Failed":"Passed"}))}function w(e,t){for(const a of e){const r=a.data?.[t];if(Array.isArray(r))return r}return[]}function Q(e){for(const t of e){const a=t.data?.skipped;if(Array.isArray(a))return a.filter(r=>typeof r=="object"&&r!==null&&"check"in r&&"reason"in r)}return[]}function X(e){const t=[...w(e,"findings")];for(const a of["critical","serious","moderate","minor"])if(t.some(r=>r.severity===a))return a}function $(e){return["critical","serious","moderate","minor"].indexOf(e??"minor")}function ee(e){return`[${e}]`}function A(e,t){const a=ae(t)||"the application";return e.kind==="responsive"?`Responsive layout — ${a}`:e.kind==="accessibility"?`Accessibility — ${a}`:`${e.title}`}function te(e,t){const a=new Date(e.startedAt).toLocaleString();return`${A(e,t)} · ${a}`}function se(e,t){const a=[`Captured by the TCR browser extension from a ${e.kind} execution.`,"",`URL: ${e.snapshot?.url??"not recorded"}`,`Executed: ${new Date(e.startedAt).toLocaleString()}`,`Steps: ${String(t.length)} (${String(t.filter(r=>r.status==="Failed").length)} failed, ${String(t.filter(r=>r.status==="Skipped").length)} not checked)`];return e.snapshot&&a.push("","Environment at the time of the run:",...Y(e.snapshot).map(r=>`· ${r}`)),a.push("",`Execution id: ${e.id}`,"Screenshots and the full findings report are attached to this run as evidence."),a.join(`
`)}function ae(e){try{return new URL(e).host}catch{return""}}async function re(e){const t=T(e.execution,e.events,e.evidence);if(t.empty)throw new Error("This execution recorded nothing that can be expressed as test steps.");const a=e.title?.trim()||t.title,r=[],n=await _.create({title:a,projectId:e.projectId,status:"Completed",priority:t.priority,testType:"Manual",description:t.description,labels:[...t.labels],testSteps:t.steps.map(p=>({action:p.action,data:p.data,expectedResult:p.expectedResult}))}),d=n.id??n._id,c=await b.create({name:e.title?.trim()?`${e.title.trim()} · ${new Date(e.execution.startedAt).toLocaleString()}`:t.runName,projectId:e.projectId,executionType:"adhoc",linkedTestCases:[{type:"TestCase",itemId:d,readableId:n.readableId,title:n.title}],tags:[...t.labels]}),l=c._id,i=e.execution.snapshot;try{await b.startRun({testRunId:l,testCaseId:d,runNumber:1,payload:{runBy:{userId:e.user?.sub??"",name:e.user?.name??e.user?.email??"TCR extension",email:e.user?.email??""},environment:i?.device?.os??"Browser",configuration:oe(i),devices:i?.device?`${i.device.browser} on ${i.device.os}`:"Chrome",version:i?.device?.browserVersion??""}})}catch(p){r.push(`The run was created but could not be started: ${p.message}`)}const h={...e.execution,context:{...e.execution.context,...e.execution.context?.projectId?{}:{projectId:e.projectId},testRunId:l,testCaseId:d,runNumber:1}};await V.upsert(h);const{uploaded:g,failed:u}=await ne(h,e.evidence);for(const[p,m]of t.steps.entries())try{await b.updateStep({testRunId:l,testCaseId:d,runNumber:1,stepId:p,status:m.status,actualResult:m.actualResult})}catch(v){r.push(`Step ${String(p+1)} could not be marked: ${v.message}`)}try{await b.finishTest({testRunId:l,testCaseId:d,timer:de(e.execution),finalize:!0})}catch(p){r.push(`The run was saved but could not be marked finished: ${p.message}`)}return{testCaseId:d,...n.readableId===void 0?{}:{testCaseReadableId:n.readableId},testRunId:l,...c.readableId===void 0?{}:{testRunReadableId:c.readableId},evidenceUploaded:g,evidenceFailed:u,warnings:r}}async function ne(e,t){const a=e.context;if(!a?.testRunId)return{uploaded:0,failed:[]};const r={entityType:"testruns",entityId:a.testRunId,folder:K(a.runNumber??1,a.testCaseId??e.id)};let n=0;const d=[];for(const c of t){if(c.bucketPath||!c.localImageKey)continue;const l=await P(c.localImageKey);if(!l){d.push(`${c.label}: the local copy has since been evicted`);continue}try{const i=await W.upload(l.blob,ie(c),r),{problem:h,...g}=c;await H.upsert({...g,bucketPath:i.bucketPath,...i.signedUrl??i.url?{signedUrl:i.signedUrl??i.url}:{}}),n+=1}catch(i){d.push(`${c.label}: ${i.message}`)}}return{uploaded:n,failed:d}}function ie(e){return`${e.label.replace(/[^a-z0-9]+/gi,"-").replace(/^-|-$/g,"").toLowerCase()||"capture"}-${String(e.timestamp)}.png`}function oe(e){if(!e)return"Unspecified";const t=[];return e.network&&e.network.presetId!=="online"&&t.push(`network: ${e.network.presetId}`),e.viewport&&t.push(`viewport: ${String(e.viewport.width)}×${String(e.viewport.height)}`),t.length?t.join(", "):"Default browser conditions"}function de(e){return e.finishedAt?Math.max(0,Math.round((e.finishedAt-e.startedAt)/1e3)):0}const C={Passed:"bg-emerald-500/12 text-emerald-700 dark:text-emerald-400",Failed:"bg-alert-orange/12 text-alert-orange",Blocked:"bg-amber-500/12 text-amber-700 dark:text-amber-400",Skipped:"bg-stroke/25 text-muted-foreground"};function ce({open:e,onClose:t,execution:a,events:r,evidence:n,onSaved:d}){const c=D(o=>o.user),l=O(o=>o.projectId),i=f.useMemo(()=>T(a,r,n),[a,r,n]),[h,g]=f.useState(i.title),[u,p]=f.useState(!1),[m,v]=f.useState(null),j=!!a.context?.testRunId,S=f.useMemo(()=>{const o={Passed:0,Failed:0,Blocked:0,Skipped:0};for(const k of i.steps)o[k.status]+=1;return o},[i.steps]),R=n.filter(o=>o.localImageKey&&!o.bucketPath).length,E=async()=>{if(!l){x.error("Pick a project first — a test case has to belong to one.");return}p(!0);try{const o=await re({execution:a,events:r,evidence:n,projectId:l,user:c,title:h});v(o),d?.(o),o.evidenceFailed.length>0?x.info(`${o.testRunReadableId??"The run"} was created — ${String(o.evidenceFailed.length)} attachments did not upload`):x.success(`Saved as ${o.testRunReadableId??"a test run"}`)}catch(o){x.error(o.message)}finally{p(!1)}};return m?s.jsxs(I,{open:e,onClose:t,title:"Saved to TCR",align:"top",children:[s.jsxs("div",{className:"space-y-2.5 text-[11px]",children:[s.jsxs("div",{className:"rounded-lg border border-emerald-500/30 bg-emerald-500/[0.06] px-3 py-2.5",children:[s.jsxs("p",{className:"font-semibold text-emerald-700 dark:text-emerald-400",children:[m.testCaseReadableId??"Test case"," · ",m.testRunReadableId??"Test run"]}),s.jsxs("p",{className:"mt-0.5 text-[10px] text-muted-foreground",children:[String(i.steps.length)," steps recorded with their verdicts",m.evidenceUploaded>0?`, ${String(m.evidenceUploaded)} attachments uploaded`:"","."]})]}),m.evidenceFailed.length>0&&s.jsx(N,{title:`${String(m.evidenceFailed.length)} attachments did not upload`,rows:m.evidenceFailed}),m.warnings.length>0&&s.jsx(N,{title:"Also worth knowing",rows:m.warnings}),s.jsx("p",{className:"text-[10px] text-muted-foreground",children:"This execution is now bound to the run, so anything else you attach to it goes there too."})]}),s.jsx("div",{className:"mt-3 flex justify-end",children:s.jsx(y,{size:"sm",onClick:t,children:"Done"})})]}):s.jsx(I,{open:e,onClose:t,title:"Save this result to TCR",description:"Creates a test case describing what was checked, and an ad-hoc run carrying the verdicts and the screenshots.",align:"top",footer:s.jsxs("div",{className:"flex items-center justify-end gap-2",children:[s.jsx(y,{size:"sm",variant:"ghost",onClick:t,disabled:u,children:"Cancel"}),s.jsxs(y,{size:"sm",onClick:()=>void E(),disabled:u||i.empty||j,children:[u?s.jsx(M,{className:"mr-1 h-3 w-3 animate-spin"}):s.jsx(q,{className:"mr-1 h-3 w-3"}),u?"Saving…":"Create case & run"]})]}),children:s.jsxs("div",{className:"space-y-3",children:[j&&s.jsx("p",{className:"rounded-lg border border-stroke bg-stroke/[0.06] px-3 py-2 text-[10px] dark:border-stroke/30",children:"This execution is already bound to a test run, so its evidence is going there. Saving again would create a duplicate case for work that is already recorded."}),i.empty?s.jsx("p",{className:"rounded-lg border border-dashed border-stroke px-3 py-4 text-center text-[10.5px] text-muted-foreground dark:border-stroke/30",children:"This execution did not record anything that can be written as test steps, so there is nothing to save. Run the tool again with the page loaded."}):s.jsxs(s.Fragment,{children:[s.jsxs("label",{className:"block",children:[s.jsx("span",{className:"mb-1 block text-[10px] font-medium uppercase tracking-wide text-muted-foreground",children:"Test case title"}),s.jsx(B,{value:h,onChange:o=>g(o.target.value),className:"h-8 text-[11px]"})]}),s.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[["Failed","Passed","Blocked","Skipped"].filter(o=>S[o]>0).map(o=>s.jsxs("span",{className:`rounded px-1.5 py-0.5 text-[9.5px] font-semibold tabular-nums ${C[o]??""}`,children:[S[o]," ",o.toLowerCase()]},o)),R>0&&s.jsxs("span",{className:"rounded bg-dynamic-azure/12 px-1.5 py-0.5 text-[9.5px] font-semibold tabular-nums text-dynamic-azure",children:[R," screenshots to upload"]})]}),s.jsxs("div",{children:[s.jsx("p",{className:"mb-1 text-[10px] font-medium uppercase tracking-wide text-muted-foreground",children:"Steps · derived from what the tool observed"}),s.jsx("div",{className:"max-h-56 space-y-1 overflow-y-auto rounded-lg border border-stroke/70 p-1.5 dark:border-stroke/25",children:i.steps.map((o,k)=>s.jsxs("div",{className:"flex gap-1.5 rounded px-1 py-1",children:[s.jsx("span",{className:`mt-px h-fit shrink-0 rounded px-1 py-0.5 text-[8.5px] font-semibold ${C[o.status]??""}`,children:o.status}),s.jsx("span",{className:"min-w-0 flex-1 break-words text-[10px] leading-snug",children:o.action})]},k))})]}),s.jsx("p",{className:"text-[9.5px] leading-snug text-muted-foreground",children:"Steps are a record of what ran, so they are not editable here. Change a verdict in the run afterwards if you disagree — there the change is attributed to you."})]})]})})}function N({title:e,rows:t}){return s.jsxs("div",{className:"rounded-lg border border-amber-500/35 bg-amber-500/[0.05] px-3 py-2",children:[s.jsx("p",{className:"text-[10px] font-semibold text-amber-700 dark:text-amber-400",children:e}),s.jsx("ul",{className:"mt-1 space-y-0.5",children:t.map((a,r)=>s.jsxs("li",{className:"text-[9.5px] leading-snug text-muted-foreground",children:["· ",a]},r))})]})}function me({execution:e,reloadKey:t}){const[a,r]=f.useState(!1),[n,d]=f.useState(null),[c,l]=f.useState([]),[i,h]=f.useState([]),g=!!e.context?.testRunId;return f.useEffect(()=>{let u=!1;return Promise.all([z(e.id),L(e.id)]).then(([p,m])=>{u||(l(p),h(m))}),()=>{u=!0}},[e.id,t]),g&&!n?s.jsx("p",{className:"rounded-lg border border-stroke bg-stroke/[0.05] px-3 py-2 text-[10px] text-muted-foreground dark:border-stroke/30",children:"This result is attached to the test run you are executing."}):s.jsxs(s.Fragment,{children:[n?s.jsxs("div",{className:"flex items-center gap-2 rounded-lg border border-emerald-500/30 bg-emerald-500/[0.06] px-3 py-2",children:[s.jsx(U,{className:"h-3.5 w-3.5 shrink-0 text-emerald-700 dark:text-emerald-400"}),s.jsxs("p",{className:"text-[10.5px] font-medium text-emerald-700 dark:text-emerald-400",children:["Saved as ",n.testRunReadableId??"a test run",n.testCaseReadableId?` against ${n.testCaseReadableId}`:""]})]}):s.jsxs("div",{className:"flex items-center gap-2 rounded-lg border border-dynamic-azure/30 bg-dynamic-azure/[0.05] px-3 py-2",children:[s.jsxs("div",{className:"min-w-0 flex-1",children:[s.jsx("p",{className:"text-[10.5px] font-semibold",children:"Keep this result"}),s.jsx("p",{className:"text-[9.5px] leading-snug text-muted-foreground",children:"Save it as a test case and run so the screenshots and findings are in TCR, not just this browser."})]}),s.jsx(y,{size:"sm",className:"h-7 shrink-0",onClick:()=>r(!0),children:"Save to TCR"})]}),a&&s.jsx(ce,{open:a,onClose:()=>r(!1),execution:e,events:c,evidence:i,onSaved:d})]})}export{q as C,ce as S,me as a};
//# sourceMappingURL=chunk-nlio5-IT.js.map
