UNPKG

pulse-dashboard

Version:

A Next.js Dashboard application for real-time monitoring and historical analysis of Playwright test executions. This component provides the UI for visualizing Playwright test results and can be run as a standalone CLI tool.

1 lines 12.2 kB
"use strict";exports.id=171,exports.ids=[171],exports.modules={29523:(e,r,t)=>{t.d(r,{$:()=>c});var s=t(60687),a=t(43210),o=t(8730),n=t(24224),i=t(4780);let l=(0,n.F)("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),c=a.forwardRef(({className:e,variant:r,size:t,asChild:a=!1,...n},c)=>{let d=a?o.DX:"button";return(0,s.jsx)(d,{className:(0,i.cn)(l({variant:r,size:t,className:e})),ref:c,...n})});c.displayName="Button"},42692:(e,r,t)=>{t.d(r,{F:()=>i});var s=t(60687),a=t(43210),o=t(68123),n=t(4780);let i=a.forwardRef(({className:e,children:r,...t},a)=>(0,s.jsxs)(o.bL,{ref:a,className:(0,n.cn)("relative overflow-hidden",e),...t,children:[(0,s.jsx)(o.LM,{className:"h-full w-full rounded-[inherit]",children:r}),(0,s.jsx)(l,{}),(0,s.jsx)(o.OK,{})]}));i.displayName=o.bL.displayName;let l=a.forwardRef(({className:e,orientation:r="vertical",...t},a)=>(0,s.jsx)(o.VM,{ref:a,orientation:r,className:(0,n.cn)("flex touch-none select-none transition-colors","vertical"===r&&"h-full w-2.5 border-l border-l-transparent p-[1px]","horizontal"===r&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",e),...t,children:(0,s.jsx)(o.lr,{className:"relative flex-1 rounded-full bg-border"})}));l.displayName=o.VM.displayName},44493:(e,r,t)=>{t.d(r,{BT:()=>c,Wu:()=>d,ZB:()=>l,Zp:()=>n,aR:()=>i});var s=t(60687),a=t(43210),o=t(4780);let n=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("div",{ref:t,className:(0,o.cn)("rounded-lg border bg-card text-card-foreground shadow-sm",e),...r}));n.displayName="Card";let i=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("div",{ref:t,className:(0,o.cn)("flex flex-col space-y-1.5 p-6",e),...r}));i.displayName="CardHeader";let l=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("div",{ref:t,className:(0,o.cn)("text-2xl font-semibold leading-none tracking-tight",e),...r}));l.displayName="CardTitle";let c=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("div",{ref:t,className:(0,o.cn)("text-sm text-muted-foreground",e),...r}));c.displayName="CardDescription";let d=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("div",{ref:t,className:(0,o.cn)("p-6 pt-0",e),...r}));d.displayName="CardContent",a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("div",{ref:t,className:(0,o.cn)("flex items-center p-6 pt-0",e),...r})).displayName="CardFooter"},48661:(e,r,t)=>{t.d(r,{O:()=>a});var s=t(43210);function a(){let[e,r]=(0,s.useState)({currentRun:null,historicalTrends:[],loadingCurrent:!0,loadingHistorical:!0,errorCurrent:null,errorHistorical:null});return(0,s.useCallback)(async()=>{let e="/api/current-run";r(e=>({...e,loadingCurrent:!0,errorCurrent:null}));try{console.log(`Attempting to fetch current run data from: ${e}`);let t=await fetch(e);if(!t.ok){let r=`${t.status} ${t.statusText||"Server Error"}`;try{let e=await t.json();e&&"string"==typeof e.message&&""!==e.message.trim()?r=e.message:e&&"object"==typeof e&&null!==e&&(r=`Server error (${t.status}): ${JSON.stringify(e)}`)}catch(r){console.warn(`Could not parse error response body as JSON for ${e}. Status: ${t.status}`,r)}throw Error(`Failed to fetch current run from ${e}: ${r}`)}let s=await t.json();r(e=>({...e,currentRun:s,loadingCurrent:!1,errorCurrent:null}))}catch(s){console.error(`PulseDashboard Fetch Error (currentRun at ${e}):`,s);let t=`An unknown error occurred while fetching current run data from ${e}.`;t=s instanceof TypeError&&s.message.toLowerCase().includes("failed to fetch")?`Network error: Could not connect to the API endpoint (${e}). Please check your network connection and ensure the server is running.`:s instanceof Error?s.message:String(s),r(e=>({...e,currentRun:null,loadingCurrent:!1,errorCurrent:t}))}},[]),(0,s.useCallback)(async()=>{let e="/api/historical-trends";r(e=>({...e,loadingHistorical:!0,errorHistorical:null}));try{console.log(`Attempting to fetch historical trends data from: ${e}`);let t=await fetch(e);if(!t.ok){let r=`${t.status} ${t.statusText||"Server Error"}`;try{let e=await t.json();e&&"string"==typeof e.message&&""!==e.message.trim()?r=e.message:e&&"object"==typeof e&&null!==e&&(r=`Server error (${t.status}): ${JSON.stringify(e)}`)}catch(r){console.warn(`Could not parse historical trends error response body as JSON for ${e}. Status: ${t.status}`,r)}throw Error(`Failed to fetch historical trends from ${e}: ${r}`)}let s=await t.json();r(e=>({...e,historicalTrends:s,loadingHistorical:!1,errorHistorical:null}))}catch(s){console.error(`PulseDashboard Fetch Error (historicalTrends at ${e}):`,s);let t=`An unknown error occurred while fetching historical trends from ${e}.`;t=s instanceof TypeError&&s.message.toLowerCase().includes("failed to fetch")?`Network error: Could not connect to the API endpoint (${e}). Please check your network connection and ensure the server is running.`:s instanceof Error?s.message:String(s),r(e=>({...e,historicalTrends:[],loadingHistorical:!1,errorHistorical:t}))}},[]),e}},70137:(e,r,t)=>{t.d(r,{$m:()=>d,As:()=>c,nD:()=>l,ub:()=>u});var s=t(60687),a=t(43210),o=t(19236),n=t(61662),i=t(4780);let l=o.bL,c=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)(o.q7,{ref:t,className:(0,i.cn)("border-b",e),...r}));c.displayName="AccordionItem";let d=a.forwardRef(({className:e,children:r,...t},a)=>(0,s.jsx)(o.Y9,{className:"flex",children:(0,s.jsxs)(o.l9,{ref:a,className:(0,i.cn)("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",e),...t,children:[r,(0,s.jsx)(n.A,{className:"h-4 w-4 shrink-0 transition-transform duration-200"})]})}));d.displayName=o.l9.displayName;let u=a.forwardRef(({className:e,children:r,...t},a)=>(0,s.jsx)(o.UC,{ref:a,className:"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",...t,children:(0,s.jsx)("div",{className:(0,i.cn)("pb-4 pt-0",e),children:r})}));u.displayName=o.UC.displayName},80754:(e,r,t)=>{t.r(r),t.d(r,{"0011e9424474535028c01a45dc1bf60dfbb2f5cfe3":()=>l,"00361f6e51232960768351a17ab2be16bd5923168d":()=>c});var s=t(91199);t(42087);var a=t(79748),o=t.n(a),n=t(33873),i=t.n(n);async function l(){console.log("[ACTIONS getRawHistoricalReports] ------------- START -------------");let e=process.env.PULSE_USER_CWD,r=process.cwd();console.log("[ACTIONS getRawHistoricalReports] process.env.PULSE_USER_CWD:",e),console.log("[ACTIONS getRawHistoricalReports] process.cwd():",r);let t=e&&""!==e.trim()?e.trim():r;console.log("[ACTIONS getRawHistoricalReports] Effective baseDir determined:",t);let s=i().join(t,"pulse-report","history");console.log("[ACTIONS getRawHistoricalReports] Attempting to read history directory:",s);try{let e=(await o().readdir(s)).filter(e=>e.startsWith("trend-")&&e.endsWith(".json"));console.log(`[ACTIONS getRawHistoricalReports] Found ${e.length} trend files in ${s}`);let r=[];for(let t of e){let e=i().join(s,t);try{let s=await o().readFile(e,"utf-8"),a=JSON.parse(s);a.run&&a.results?(void 0===a.run.flakinessRate&&(a.run.flakinessRate=0),r.push(a)):console.warn(`[ACTIONS getRawHistoricalReports] Skipping invalid historical report file (missing run or results): ${t}`)}catch(e){console.error(`[ACTIONS getRawHistoricalReports] Error reading or parsing historical file ${t}:`,e)}}return r.sort((e,r)=>new Date(e.run.timestamp).getTime()-new Date(r.run.timestamp).getTime()),console.log("[ACTIONS getRawHistoricalReports] ------------- END (SUCCESS) -------------"),r}catch(e){return console.error(`[ACTIONS getRawHistoricalReports] Error accessing or reading historical trends directory ${s}:`,e.message),e instanceof Error&&"ENOENT"===e.code&&console.warn(`[ACTIONS getRawHistoricalReports] History directory not found at ${s}. This is normal if no historical reports exist yet.`),console.log("[ACTIONS getRawHistoricalReports] ------------- END (ERROR) -------------"),[]}}async function c(){try{let e=await l();if(0===e.length)return console.log("[ACTIONS getFlakyTestsAnalysis] No historical reports found or an error occurred in getRawHistoricalReports. Returning empty flaky tests."),{success:!0,flakyTests:[]};let r=new Map;for(let t of e){if(!t.results){console.warn("[ACTIONS getFlakyTestsAnalysis] Skipping a report in history due to missing .results property.");continue}for(let e of t.results)r.has(e.id)||r.set(e.id,{name:e.name,suiteName:e.suiteName,occurrences:[]}),r.get(e.id).occurrences.push({runTimestamp:t.run.timestamp,status:e.status})}let t=[];for(let[e,s]of r.entries()){let r=new Set(s.occurrences.map(e=>e.status)),a=r.has("passed"),o=r.has("failed")||r.has("timedOut");if(a&&o){let r=0,a=0,o=0,n=0;s.occurrences.forEach(e=>{"passed"===e.status?r++:"failed"===e.status||"timedOut"===e.status?a++:"skipped"===e.status?o++:"pending"===e.status&&n++});let i=s.occurrences.sort((e,r)=>new Date(e.runTimestamp).getTime()-new Date(r.runTimestamp).getTime());t.push({id:e,name:s.name,suiteName:s.suiteName,occurrences:i,passedCount:r,failedCount:a,skippedCount:o,pendingCount:n,totalRuns:s.occurrences.length,firstSeen:i[0]?.runTimestamp||"",lastSeen:i[i.length-1]?.runTimestamp||""})}}return t.sort((e,r)=>r.failedCount/r.totalRuns-e.failedCount/e.totalRuns||r.totalRuns-e.totalRuns),{success:!0,flakyTests:t}}catch(e){return console.error("[ACTIONS getFlakyTestsAnalysis] Error analyzing flaky tests:",e),{success:!1,error:e instanceof Error?e.message:"An unknown error occurred during flaky test analysis."}}}(0,t(33331).D)([l,c]),(0,s.A)(l,"0011e9424474535028c01a45dc1bf60dfbb2f5cfe3",null),(0,s.A)(c,"00361f6e51232960768351a17ab2be16bd5923168d",null)},85726:(e,r,t)=>{t.d(r,{E:()=>o});var s=t(60687),a=t(4780);function o({className:e,...r}){return(0,s.jsx)("div",{className:(0,a.cn)("animate-pulse rounded-md bg-muted",e),...r})}},91821:(e,r,t)=>{t.d(r,{Fc:()=>l,TN:()=>d,XL:()=>c});var s=t(60687),a=t(43210),o=t(24224),n=t(4780);let i=(0,o.F)("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",{variants:{variant:{default:"bg-background text-foreground",destructive:"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"}},defaultVariants:{variant:"default"}}),l=a.forwardRef(({className:e,variant:r,...t},a)=>(0,s.jsx)("div",{ref:a,role:"alert",className:(0,n.cn)(i({variant:r}),e),...t}));l.displayName="Alert";let c=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("h5",{ref:t,className:(0,n.cn)("mb-1 font-medium leading-none tracking-tight",e),...r}));c.displayName="AlertTitle";let d=a.forwardRef(({className:e,...r},t)=>(0,s.jsx)("div",{ref:t,className:(0,n.cn)("text-sm [&_p]:leading-relaxed",e),...r}));d.displayName="AlertDescription"},96834:(e,r,t)=>{t.d(r,{E:()=>i});var s=t(60687);t(43210);var a=t(24224),o=t(4780);let n=(0,a.F)("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",secondary:"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",destructive:"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",outline:"text-foreground"}},defaultVariants:{variant:"default"}});function i({className:e,variant:r,...t}){return(0,s.jsx)("div",{className:(0,o.cn)(n({variant:r}),e),...t})}}};