playwright-logbook 0.2.0
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.
- package/LICENSE +21 -0
- package/README.md +134 -0
- package/dist/artifacts.d.ts +7 -0
- package/dist/artifacts.js +35 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/caseids.d.ts +12 -0
- package/dist/caseids.js +24 -0
- package/dist/caseids.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.js +6 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/debug.d.ts +7 -0
- package/dist/cli/commands/debug.js +14 -0
- package/dist/cli/commands/debug.js.map +1 -0
- package/dist/cli/commands/flaky.d.ts +8 -0
- package/dist/cli/commands/flaky.js +27 -0
- package/dist/cli/commands/flaky.js.map +1 -0
- package/dist/cli/commands/history.d.ts +8 -0
- package/dist/cli/commands/history.js +24 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/merge.d.ts +12 -0
- package/dist/cli/commands/merge.js +102 -0
- package/dist/cli/commands/merge.js.map +1 -0
- package/dist/cli/commands/report.d.ts +9 -0
- package/dist/cli/commands/report.js +13 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/summary.d.ts +7 -0
- package/dist/cli/commands/summary.js +14 -0
- package/dist/cli/commands/summary.js.map +1 -0
- package/dist/cli/format.d.ts +18 -0
- package/dist/cli/format.js +41 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/program.d.ts +12 -0
- package/dist/cli/program.js +74 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/clientlib.d.ts +48 -0
- package/dist/clientlib.js +136 -0
- package/dist/clientlib.js.map +1 -0
- package/dist/collect.d.ts +101 -0
- package/dist/collect.js +50 -0
- package/dist/collect.js.map +1 -0
- package/dist/debugpacket.d.ts +31 -0
- package/dist/debugpacket.js +105 -0
- package/dist/debugpacket.js.map +1 -0
- package/dist/env.d.ts +41 -0
- package/dist/env.js +49 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +10 -0
- package/dist/errors.js.map +1 -0
- package/dist/history.d.ts +32 -0
- package/dist/history.js +72 -0
- package/dist/history.js.map +1 -0
- package/dist/index.cjs +1562 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/merge.d.ts +9 -0
- package/dist/merge.js +64 -0
- package/dist/merge.js.map +1 -0
- package/dist/model.d.ts +98 -0
- package/dist/model.js +129 -0
- package/dist/model.js.map +1 -0
- package/dist/options.d.ts +23 -0
- package/dist/options.js +5 -0
- package/dist/options.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.js +17 -0
- package/dist/paths.js.map +1 -0
- package/dist/publish.d.ts +14 -0
- package/dist/publish.js +2 -0
- package/dist/publish.js.map +1 -0
- package/dist/render.d.ts +6 -0
- package/dist/render.js +50 -0
- package/dist/render.js.map +1 -0
- package/dist/reporter.d.ts +53 -0
- package/dist/reporter.js +161 -0
- package/dist/reporter.js.map +1 -0
- package/dist/sanitize.d.ts +11 -0
- package/dist/sanitize.js +33 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/schema.d.ts +581 -0
- package/dist/schema.js +31 -0
- package/dist/schema.js.map +1 -0
- package/dist/signals.d.ts +9 -0
- package/dist/signals.js +37 -0
- package/dist/signals.js.map +1 -0
- package/dist/store.d.ts +41 -0
- package/dist/store.js +142 -0
- package/dist/store.js.map +1 -0
- package/dist/template/css.d.ts +1 -0
- package/dist/template/css.js +17 -0
- package/dist/template/css.js.map +1 -0
- package/dist/template/icons.d.ts +1 -0
- package/dist/template/icons.js +9 -0
- package/dist/template/icons.js.map +1 -0
- package/dist/template/js/core.d.ts +1 -0
- package/dist/template/js/core.js +90 -0
- package/dist/template/js/core.js.map +1 -0
- package/dist/template/js/failures.d.ts +1 -0
- package/dist/template/js/failures.js +33 -0
- package/dist/template/js/failures.js.map +1 -0
- package/dist/template/js/help.d.ts +1 -0
- package/dist/template/js/help.js +4 -0
- package/dist/template/js/help.js.map +1 -0
- package/dist/template/js/panel.d.ts +1 -0
- package/dist/template/js/panel.js +84 -0
- package/dist/template/js/panel.js.map +1 -0
- package/dist/template/js/project.d.ts +1 -0
- package/dist/template/js/project.js +40 -0
- package/dist/template/js/project.js.map +1 -0
- package/dist/template/js/run.d.ts +1 -0
- package/dist/template/js/run.js +38 -0
- package/dist/template/js/run.js.map +1 -0
- package/dist/template/js/tests.d.ts +1 -0
- package/dist/template/js/tests.js +23 -0
- package/dist/template/js/tests.js.map +1 -0
- package/dist/template/js/trends.d.ts +1 -0
- package/dist/template/js/trends.js +57 -0
- package/dist/template/js/trends.js.map +1 -0
- package/dist/template/tokens.d.ts +45 -0
- package/dist/template/tokens.js +12 -0
- package/dist/template/tokens.js.map +1 -0
- package/dist/template.d.ts +2 -0
- package/dist/template.js +19 -0
- package/dist/template.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const PROJECT_JS = `
|
|
2
|
+
function renderProject(){
|
|
3
|
+
const panel=document.getElementById('tab-project');clear(panel);const info=model.run.project;
|
|
4
|
+
panel.appendChild(h('h2',{text:'Project'}));
|
|
5
|
+
panel.appendChild(h('p',{class:'muted',text:(info.name||'(unnamed)')+' · '+(info.configFile||'No config file')}));
|
|
6
|
+
panel.appendChild(h('h3',{text:'Playwright projects'}));
|
|
7
|
+
const cards=h('div',{class:'grid-cards'});
|
|
8
|
+
for(const item of model.projects||[]){
|
|
9
|
+
const rate=item.total?Math.round(item.passed/item.total*100):0;
|
|
10
|
+
cards.appendChild(h('div',{class:'section-card'},h('strong',{text:item.name||'(default)'}),
|
|
11
|
+
h('p',{text:item.total+' tests · '+rate+'% passed'}),h('small',{text:formatDuration(item.durationMs)})));
|
|
12
|
+
}
|
|
13
|
+
panel.appendChild(cards);
|
|
14
|
+
panel.appendChild(h('h3',{text:'Files'}));
|
|
15
|
+
const sort=h('select',{'aria-label':'Sort files'});
|
|
16
|
+
for(const [value,label] of [['file','File'],['failed','Most failed'],['flaky','Most flaky'],['durationMs','Slowest']])sort.appendChild(h('option',{value,text:label}));
|
|
17
|
+
panel.appendChild(sort);const files=h('div',{});panel.appendChild(files);
|
|
18
|
+
function drawFiles(){
|
|
19
|
+
clear(files);const key=sort.value;
|
|
20
|
+
const ordered=[...model.files].sort((a,b)=>key==='file'?(a.file<b.file?-1:a.file>b.file?1:0):b[key]-a[key]||(a.file<b.file?-1:1));
|
|
21
|
+
const rows=ordered.map(item=>{
|
|
22
|
+
const failed=h('span',{},String(item.failed),h('span',{class:'heat hot'},h('span',{style:'width:'+(item.total?Math.round(item.failed/item.total*100):0)+'%'})));
|
|
23
|
+
const flaky=h('span',{},String(item.flaky),h('span',{class:'heat'},h('span',{style:'width:'+(item.total?Math.round(item.flaky/item.total*100):0)+'%'})));
|
|
24
|
+
return [item.file,item.total,failed,flaky,item.skipped,formatDuration(item.durationMs)];
|
|
25
|
+
});
|
|
26
|
+
files.appendChild(table(['File','Total','Failed','Flaky','Skipped','Duration'],rows));
|
|
27
|
+
}
|
|
28
|
+
sort.addEventListener('change',drawFiles);drawFiles();
|
|
29
|
+
panel.appendChild(h('h3',{text:'Tags'}));const tags=h('div',{class:'toolbar'});
|
|
30
|
+
for(const item of model.tags){const button=h('button',{class:'chip-button',type:'button',text:item.tag+' · '+item.count});
|
|
31
|
+
button.addEventListener('click',()=>setState({tab:'tests',tag:item.tag}));tags.appendChild(button)}
|
|
32
|
+
panel.appendChild(tags);panel.appendChild(h('h3',{text:'Slowest tests'}));
|
|
33
|
+
panel.appendChild(table(['Test','File','Project','Duration'],model.slowest.map(item=>{
|
|
34
|
+
const button=h('button',{class:'button',type:'button',text:item.title});
|
|
35
|
+
button.addEventListener('click',()=>openTest(item.testId,button));
|
|
36
|
+
return [button,item.file,item.project,formatDuration(item.durationMs)];
|
|
37
|
+
})));
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/template/js/project.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const RUN_JS = "\nfunction renderRun(){\n const panel=document.getElementById('tab-run');clear(panel);panel.appendChild(h('h2',{text:'Run details'}));\n const run=model.run,env=run.env,cards=h('div',{class:'grid-cards'});\n const sections=[\n ['CI',[['Provider',env.ci?.provider],['Build ID',env.ci?.buildId]]],\n ['Git',[['Branch',env.git.branch],['Commit',env.git.commit],['PR',env.git.prNumber]]],\n ['Machine',[['OS',env.machine.os],['Architecture',env.machine.arch],['Node',env.machine.node],['CPUs',env.machine.cpus]]],\n ['Playwright',[['Version',env.playwrightVersion],['Workers',env.workers]]],\n ['Shards',[['Expected',run.expectedShards],['Received',run.receivedShards.join(', ')]]]\n ];\n for(const [name,values] of sections)cards.appendChild(h('div',{class:'section-card'},h('h3',{text:name}),...values.map(([label,value])=>h('p',{},label+': '+(value??'\u2014')))));\n panel.appendChild(cards);\n if(env.ci?.buildUrl)panel.appendChild(link('Open CI build',env.ci.buildUrl));\n panel.appendChild(h('h3',{text:'Timeline \u00B7 approximate'}));\n if(run.expectedShards!==1){panel.appendChild(h('p',{class:'muted',text:'Timeline is available for unsharded runs.'}));return}\n const tests=run.tests.filter(test=>test.timing).sort((a,b)=>b.durationMs-a.durationMs).slice(0,1500);\n if(run.tests.length>1500)panel.appendChild(h('p',{class:'muted',text:'Showing the 1500 longest tests.'}));\n if(!tests.length){panel.appendChild(h('p',{class:'muted',text:'No timing data available.'}));return}\n const starts=tests.map(test=>Date.parse(test.timing.startedAt));\n const min=Math.min(...starts),max=Math.max(...tests.map((test,index)=>starts[index]+test.durationMs));\n const workers=[...new Set(tests.map(test=>test.timing.workerIndex))].sort((a,b)=>a-b);\n const chart=s('svg',{class:'chart timeline',viewBox:'0 0 800 '+Math.max(160,workers.length*34+30),role:'img','aria-label':'Test timeline'});\n tests.forEach((test,index)=>{\n const x=70+700*(starts[index]-min)/Math.max(1,max-min);\n const width=Math.max(2,700*test.durationMs/Math.max(1,max-min));\n const y=15+workers.indexOf(test.timing.workerIndex)*34;\n const rect=s('rect',{x,y,width,height:20,class:statusKind(test),tabindex:'0'});\n rect.appendChild(s('title',{},test.title+' \u00B7 '+formatDuration(test.durationMs)));\n rect.addEventListener('click',()=>openTest(test.testId));\n rect.addEventListener('keydown',event=>{if(event.key==='Enter'||event.key===' '){event.preventDefault();openTest(test.testId)}});\n chart.appendChild(rect);\n });\n workers.forEach((worker,index)=>chart.appendChild(s('text',{x:4,y:30+index*34},'W'+worker)));\n panel.appendChild(h('div',{class:'table-wrap'},chart));\n}\n";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const RUN_JS = `
|
|
2
|
+
function renderRun(){
|
|
3
|
+
const panel=document.getElementById('tab-run');clear(panel);panel.appendChild(h('h2',{text:'Run details'}));
|
|
4
|
+
const run=model.run,env=run.env,cards=h('div',{class:'grid-cards'});
|
|
5
|
+
const sections=[
|
|
6
|
+
['CI',[['Provider',env.ci?.provider],['Build ID',env.ci?.buildId]]],
|
|
7
|
+
['Git',[['Branch',env.git.branch],['Commit',env.git.commit],['PR',env.git.prNumber]]],
|
|
8
|
+
['Machine',[['OS',env.machine.os],['Architecture',env.machine.arch],['Node',env.machine.node],['CPUs',env.machine.cpus]]],
|
|
9
|
+
['Playwright',[['Version',env.playwrightVersion],['Workers',env.workers]]],
|
|
10
|
+
['Shards',[['Expected',run.expectedShards],['Received',run.receivedShards.join(', ')]]]
|
|
11
|
+
];
|
|
12
|
+
for(const [name,values] of sections)cards.appendChild(h('div',{class:'section-card'},h('h3',{text:name}),...values.map(([label,value])=>h('p',{},label+': '+(value??'—')))));
|
|
13
|
+
panel.appendChild(cards);
|
|
14
|
+
if(env.ci?.buildUrl)panel.appendChild(link('Open CI build',env.ci.buildUrl));
|
|
15
|
+
panel.appendChild(h('h3',{text:'Timeline · approximate'}));
|
|
16
|
+
if(run.expectedShards!==1){panel.appendChild(h('p',{class:'muted',text:'Timeline is available for unsharded runs.'}));return}
|
|
17
|
+
const tests=run.tests.filter(test=>test.timing).sort((a,b)=>b.durationMs-a.durationMs).slice(0,1500);
|
|
18
|
+
if(run.tests.length>1500)panel.appendChild(h('p',{class:'muted',text:'Showing the 1500 longest tests.'}));
|
|
19
|
+
if(!tests.length){panel.appendChild(h('p',{class:'muted',text:'No timing data available.'}));return}
|
|
20
|
+
const starts=tests.map(test=>Date.parse(test.timing.startedAt));
|
|
21
|
+
const min=Math.min(...starts),max=Math.max(...tests.map((test,index)=>starts[index]+test.durationMs));
|
|
22
|
+
const workers=[...new Set(tests.map(test=>test.timing.workerIndex))].sort((a,b)=>a-b);
|
|
23
|
+
const chart=s('svg',{class:'chart timeline',viewBox:'0 0 800 '+Math.max(160,workers.length*34+30),role:'img','aria-label':'Test timeline'});
|
|
24
|
+
tests.forEach((test,index)=>{
|
|
25
|
+
const x=70+700*(starts[index]-min)/Math.max(1,max-min);
|
|
26
|
+
const width=Math.max(2,700*test.durationMs/Math.max(1,max-min));
|
|
27
|
+
const y=15+workers.indexOf(test.timing.workerIndex)*34;
|
|
28
|
+
const rect=s('rect',{x,y,width,height:20,class:statusKind(test),tabindex:'0'});
|
|
29
|
+
rect.appendChild(s('title',{},test.title+' · '+formatDuration(test.durationMs)));
|
|
30
|
+
rect.addEventListener('click',()=>openTest(test.testId));
|
|
31
|
+
rect.addEventListener('keydown',event=>{if(event.key==='Enter'||event.key===' '){event.preventDefault();openTest(test.testId)}});
|
|
32
|
+
chart.appendChild(rect);
|
|
33
|
+
});
|
|
34
|
+
workers.forEach((worker,index)=>chart.appendChild(s('text',{x:4,y:30+index*34},'W'+worker)));
|
|
35
|
+
panel.appendChild(h('div',{class:'table-wrap'},chart));
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/template/js/run.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TESTS_JS = "\nlet testsReady=false,showCount=200,searchTimer=0;\nfunction renderTests(){const panel=document.getElementById('tab-tests');if(!testsReady){testsReady=true;const toolbar=h('div',{class:'toolbar'});const search=h('input',{id:'lb-search',type:'search','aria-label':'Search tests',placeholder:'Search tests'});search.value=state.q;search.addEventListener('input',()=>{clearTimeout(searchTimer);searchTimer=setTimeout(()=>setState({q:search.value}),120)});toolbar.appendChild(search);const counts={passed:0,failed:0,flaky:0,skipped:0};for(const test of allTests){const kind=statusKind(test);counts[kind==='timedout'?'failed':kind]++}for(const kind of ['passed','failed','flaky','skipped']){const button=h('button',{class:'chip-button','data-status':kind,type:'button'},kind+' '+counts[kind]);button.addEventListener('click',()=>setState({status:state.status.includes(kind)?state.status.filter(item=>item!==kind):[...state.status,kind]}));toolbar.appendChild(button)}const project=h('select',{id:'lb-project','aria-label':'Filter project'},h('option',{value:'',text:'All projects'}));for(const name of [...new Set(allTests.map(test=>test.project))].sort())project.appendChild(h('option',{value:name,text:name||'(default)'}));project.addEventListener('change',()=>setState({project:project.value}));toolbar.appendChild(project);const tag=h('select',{id:'lb-tag','aria-label':'Filter tag'},h('option',{value:'',text:'All tags'}));for(const name of [...new Set(allTests.flatMap(test=>test.tags))].sort())tag.appendChild(h('option',{value:name,text:name}));tag.addEventListener('change',()=>setState({tag:tag.value}));toolbar.appendChild(tag);const sort=h('select',{id:'lb-sort','aria-label':'Sort tests'});for(const [value,label] of [['default','Default'],['slowest','Slowest'],['fastest','Fastest'],['title','Title'],['attempts','Most attempts'],['severity','Severity']])sort.appendChild(h('option',{value,text:label}));sort.addEventListener('change',()=>setState({sort:sort.value}));toolbar.appendChild(sort);const group=h('button',{id:'lb-group',class:'chip-button',type:'button',text:'Group by file'});group.addEventListener('click',()=>setState({group:state.group==='file'?'none':'file'}));toolbar.appendChild(group);if(model.comparison){const changed=h('button',{id:'lb-changed',class:'chip-button',type:'button',text:'Changed'});changed.addEventListener('click',()=>setState({changed:!state.changed}));toolbar.appendChild(changed)}panel.appendChild(toolbar);panel.appendChild(h('p',{id:'lb-result-count',class:'muted'}));panel.appendChild(h('div',{class:'table-wrap'},h('table',{},h('thead',{},h('tr',{},['Status','Test','Project','Tags / case IDs','Duration','Attempts','Last 10'].map(item=>h('th',{text:item})))),h('tbody',{id:'lb-tests-body'}))));panel.appendChild(h('button',{id:'lb-more',class:'button',type:'button',text:'Show 200 more'}));document.getElementById('lb-more').addEventListener('click',()=>{showCount+=200;renderTests()})}const search=document.getElementById('lb-search');if(document.activeElement!==search)search.value=state.q;document.getElementById('lb-project').value=state.project;document.getElementById('lb-tag').value=state.tag;document.getElementById('lb-sort').value=state.sort;document.getElementById('lb-group').setAttribute('aria-pressed',String(state.group==='file'));document.getElementById('lb-changed')?.setAttribute('aria-pressed',String(state.changed));for(const button of panel.querySelectorAll('[data-status]'))button.setAttribute('aria-pressed',String(state.status.includes(button.dataset.status)));const changedIds=model.comparison?[...model.comparison.newFailures,...model.comparison.fixed,...model.comparison.newTests].map(item=>item.testId):[];visibleRows=sortTests(filterTests(allTests,state,{changedIds}),state.sort);document.getElementById('lb-result-count').textContent=visibleRows.length+' of '+allTests.length+' tests';const body=document.getElementById('lb-tests-body');clear(body);const max=Math.max(1,...allTests.map(test=>test.durationMs));const durations=allTests.map(test=>test.durationMs).sort((a,b)=>a-b);const p90=durations[Math.floor(durations.length*.9)]||0;const shown=visibleRows.slice(0,showCount);if(!shown.length)body.appendChild(h('tr',{},h('td',{colspan:'7',class:'empty',text:'No tests match these filters.'})));let lastFile='';for(const test of shown){if(state.group==='file'&&test.file!==lastFile){lastFile=test.file;body.appendChild(h('tr',{class:'group-header'},h('td',{colspan:'7',text:test.file+' \u00B7 '+visibleRows.filter(item=>item.file===test.file).length+' tests'})))}const kind=statusKind(test);const name=h('td',{},h('strong',{text:test.title,title:test.title}),h('small',{text:test.file+':'+test.line}),test.firstError?h('small',{text:test.firstError.message.split('\\n')[0]}):null);const tags=h('td',{},test.tags.slice(0,3).join(' '),test.tags.length>3?' +'+(test.tags.length-3):'',h('small',{text:test.caseIds.join(' ')}));const heat=heatLevel(test.durationMs,max,p90);const duration=h('td',{},formatDuration(test.durationMs),h('span',{class:'heat'+(heat.hot?' hot':'')},h('span',{style:'width:'+heat.percent+'%'})));const row=h('tr',{'data-test-id':test.testId,tabindex:'0'},h('td',{},chip(kind)),name,h('td',{text:test.project||'(default)'}),tags,duration,h('td',{text:test.attemptCount}),h('td',{},recentStrip(model.recent?.[test.testId])));row.addEventListener('click',()=>openTest(test.testId,row));body.appendChild(row)}const more=document.getElementById('lb-more');more.hidden=visibleRows.length<=showCount;more.textContent='Show 200 more ('+(visibleRows.length-showCount)+' left)'}\nfunction renderPagination(){\n const panel=document.getElementById('tab-tests'),more=document.getElementById('lb-more');\n let footer=document.getElementById('lb-pagination');\n if(!footer){\n footer=h('div',{id:'lb-pagination',class:'pagination'});\n footer.appendChild(h('p',{id:'lb-pagination-note','aria-live':'polite'}));\n footer.appendChild(more);\n panel.appendChild(footer);\n more.addEventListener('click',renderPagination);\n }\n const shown=Math.min(showCount,visibleRows.length),remaining=visibleRows.length-shown;\n footer.hidden=remaining<=0;\n more.hidden=remaining<=0;\n if(remaining>0){\n document.getElementById('lb-pagination-note').textContent='Showing '+shown+' of '+visibleRows.length+' matching tests. Rows load in batches to keep this report responsive.';\n more.textContent='Show next '+Math.min(200,remaining)+' tests';\n }\n}\n";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const TESTS_JS = `
|
|
2
|
+
let testsReady=false,showCount=200,searchTimer=0;
|
|
3
|
+
function renderTests(){const panel=document.getElementById('tab-tests');if(!testsReady){testsReady=true;const toolbar=h('div',{class:'toolbar'});const search=h('input',{id:'lb-search',type:'search','aria-label':'Search tests',placeholder:'Search tests'});search.value=state.q;search.addEventListener('input',()=>{clearTimeout(searchTimer);searchTimer=setTimeout(()=>setState({q:search.value}),120)});toolbar.appendChild(search);const counts={passed:0,failed:0,flaky:0,skipped:0};for(const test of allTests){const kind=statusKind(test);counts[kind==='timedout'?'failed':kind]++}for(const kind of ['passed','failed','flaky','skipped']){const button=h('button',{class:'chip-button','data-status':kind,type:'button'},kind+' '+counts[kind]);button.addEventListener('click',()=>setState({status:state.status.includes(kind)?state.status.filter(item=>item!==kind):[...state.status,kind]}));toolbar.appendChild(button)}const project=h('select',{id:'lb-project','aria-label':'Filter project'},h('option',{value:'',text:'All projects'}));for(const name of [...new Set(allTests.map(test=>test.project))].sort())project.appendChild(h('option',{value:name,text:name||'(default)'}));project.addEventListener('change',()=>setState({project:project.value}));toolbar.appendChild(project);const tag=h('select',{id:'lb-tag','aria-label':'Filter tag'},h('option',{value:'',text:'All tags'}));for(const name of [...new Set(allTests.flatMap(test=>test.tags))].sort())tag.appendChild(h('option',{value:name,text:name}));tag.addEventListener('change',()=>setState({tag:tag.value}));toolbar.appendChild(tag);const sort=h('select',{id:'lb-sort','aria-label':'Sort tests'});for(const [value,label] of [['default','Default'],['slowest','Slowest'],['fastest','Fastest'],['title','Title'],['attempts','Most attempts'],['severity','Severity']])sort.appendChild(h('option',{value,text:label}));sort.addEventListener('change',()=>setState({sort:sort.value}));toolbar.appendChild(sort);const group=h('button',{id:'lb-group',class:'chip-button',type:'button',text:'Group by file'});group.addEventListener('click',()=>setState({group:state.group==='file'?'none':'file'}));toolbar.appendChild(group);if(model.comparison){const changed=h('button',{id:'lb-changed',class:'chip-button',type:'button',text:'Changed'});changed.addEventListener('click',()=>setState({changed:!state.changed}));toolbar.appendChild(changed)}panel.appendChild(toolbar);panel.appendChild(h('p',{id:'lb-result-count',class:'muted'}));panel.appendChild(h('div',{class:'table-wrap'},h('table',{},h('thead',{},h('tr',{},['Status','Test','Project','Tags / case IDs','Duration','Attempts','Last 10'].map(item=>h('th',{text:item})))),h('tbody',{id:'lb-tests-body'}))));panel.appendChild(h('button',{id:'lb-more',class:'button',type:'button',text:'Show 200 more'}));document.getElementById('lb-more').addEventListener('click',()=>{showCount+=200;renderTests()})}const search=document.getElementById('lb-search');if(document.activeElement!==search)search.value=state.q;document.getElementById('lb-project').value=state.project;document.getElementById('lb-tag').value=state.tag;document.getElementById('lb-sort').value=state.sort;document.getElementById('lb-group').setAttribute('aria-pressed',String(state.group==='file'));document.getElementById('lb-changed')?.setAttribute('aria-pressed',String(state.changed));for(const button of panel.querySelectorAll('[data-status]'))button.setAttribute('aria-pressed',String(state.status.includes(button.dataset.status)));const changedIds=model.comparison?[...model.comparison.newFailures,...model.comparison.fixed,...model.comparison.newTests].map(item=>item.testId):[];visibleRows=sortTests(filterTests(allTests,state,{changedIds}),state.sort);document.getElementById('lb-result-count').textContent=visibleRows.length+' of '+allTests.length+' tests';const body=document.getElementById('lb-tests-body');clear(body);const max=Math.max(1,...allTests.map(test=>test.durationMs));const durations=allTests.map(test=>test.durationMs).sort((a,b)=>a-b);const p90=durations[Math.floor(durations.length*.9)]||0;const shown=visibleRows.slice(0,showCount);if(!shown.length)body.appendChild(h('tr',{},h('td',{colspan:'7',class:'empty',text:'No tests match these filters.'})));let lastFile='';for(const test of shown){if(state.group==='file'&&test.file!==lastFile){lastFile=test.file;body.appendChild(h('tr',{class:'group-header'},h('td',{colspan:'7',text:test.file+' · '+visibleRows.filter(item=>item.file===test.file).length+' tests'})))}const kind=statusKind(test);const name=h('td',{},h('strong',{text:test.title,title:test.title}),h('small',{text:test.file+':'+test.line}),test.firstError?h('small',{text:test.firstError.message.split('\\n')[0]}):null);const tags=h('td',{},test.tags.slice(0,3).join(' '),test.tags.length>3?' +'+(test.tags.length-3):'',h('small',{text:test.caseIds.join(' ')}));const heat=heatLevel(test.durationMs,max,p90);const duration=h('td',{},formatDuration(test.durationMs),h('span',{class:'heat'+(heat.hot?' hot':'')},h('span',{style:'width:'+heat.percent+'%'})));const row=h('tr',{'data-test-id':test.testId,tabindex:'0'},h('td',{},chip(kind)),name,h('td',{text:test.project||'(default)'}),tags,duration,h('td',{text:test.attemptCount}),h('td',{},recentStrip(model.recent?.[test.testId])));row.addEventListener('click',()=>openTest(test.testId,row));body.appendChild(row)}const more=document.getElementById('lb-more');more.hidden=visibleRows.length<=showCount;more.textContent='Show 200 more ('+(visibleRows.length-showCount)+' left)'}
|
|
4
|
+
function renderPagination(){
|
|
5
|
+
const panel=document.getElementById('tab-tests'),more=document.getElementById('lb-more');
|
|
6
|
+
let footer=document.getElementById('lb-pagination');
|
|
7
|
+
if(!footer){
|
|
8
|
+
footer=h('div',{id:'lb-pagination',class:'pagination'});
|
|
9
|
+
footer.appendChild(h('p',{id:'lb-pagination-note','aria-live':'polite'}));
|
|
10
|
+
footer.appendChild(more);
|
|
11
|
+
panel.appendChild(footer);
|
|
12
|
+
more.addEventListener('click',renderPagination);
|
|
13
|
+
}
|
|
14
|
+
const shown=Math.min(showCount,visibleRows.length),remaining=visibleRows.length-shown;
|
|
15
|
+
footer.hidden=remaining<=0;
|
|
16
|
+
more.hidden=remaining<=0;
|
|
17
|
+
if(remaining>0){
|
|
18
|
+
document.getElementById('lb-pagination-note').textContent='Showing '+shown+' of '+visibleRows.length+' matching tests. Rows load in batches to keep this report responsive.';
|
|
19
|
+
more.textContent='Show next '+Math.min(200,remaining)+' tests';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
//# sourceMappingURL=tests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tests.js","sourceRoot":"","sources":["../../../src/template/js/tests.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TRENDS_JS = "\nfunction renderTrends(){\n const panel=document.getElementById('tab-trends');clear(panel);panel.appendChild(h('h2',{text:'Trends'}));\n const history=model.history||[];\n if(history.length<2){panel.appendChild(h('p',{class:'empty',text:'Run the suite more times to see trends.'}));return}\n const branches=[...new Set(history.map(item=>item.branch).filter(Boolean))].sort();\n const select=h('select',{'aria-label':'Filter branch'},h('option',{value:'',text:'All branches'}));\n for(const branch of branches)select.appendChild(h('option',{value:branch,text:branch}));\n panel.appendChild(select);const content=h('div',{});panel.appendChild(content);\n select.addEventListener('change',draw);\n function draw(){\n clear(content);const values=history.filter(item=>!select.value||item.branch===select.value);\n const maxDuration=Math.max(1,...values.map(item=>item.durationMs));\n const chart=s('svg',{class:'chart',viewBox:'0 0 800 190',role:'img','aria-label':'Pass rate and duration over runs'});\n const coordinates=[];\n values.forEach((item,index)=>{\n const x=25+(values.length===1?375:index*750/(values.length-1));\n const rate=item.summary.total?item.summary.passed/item.summary.total:0;\n const y=150-120*rate;\n coordinates.push([x,y]);\n const barHeight=70*item.durationMs/maxDuration;\n const bar=s('rect',{x:x-7,y:165-barHeight,width:14,height:barHeight});\n bar.appendChild(s('title',{},item.runId+' \u00B7 '+formatDuration(item.durationMs)));\n chart.appendChild(bar);\n });\n const points=coordinates.map(([x,y])=>x+','+y).join(' ');\n const area=s('polygon',{points:'25,165 '+points+' 775,165',class:'trend-area'});\n chart.appendChild(area);chart.appendChild(s('polyline',{points,class:'trend-line'}));\n values.forEach((item,index)=>{\n const [x,y]=coordinates[index];const dot=s('circle',{cx:x,cy:y,r:4,class:'trend-dot'});\n dot.appendChild(s('title',{},item.runId+' \u00B7 '+item.status));\n chart.appendChild(dot);\n });\n content.appendChild(chart);\n const strip=h('div',{class:'run-strip','aria-label':'Run status history'});\n for(const item of values)strip.appendChild(h('span',{class:item.status==='passed'?'passed':'failed',title:item.runId+' \u00B7 '+item.status,'aria-label':item.runId+' '+item.status}));\n content.appendChild(strip);\n content.appendChild(table(['Run','Date','Branch','Status','Pass rate','Duration'],values.map(item=>[\n item.runId+(item.runId===model.run.runId?' \u00B7 current':''),item.startedAt,item.branch||'',item.status,\n (item.summary.total?Math.round(100*item.summary.passed/item.summary.total):0)+'%',formatDuration(item.durationMs)\n ])));\n }\n draw();\n}\nfunction renderFlaky(){\n const panel=document.getElementById('tab-flaky');clear(panel);panel.appendChild(h('h2',{text:'Flaky tests'}));\n if(!model.flaky?.length){panel.appendChild(h('p',{class:'empty',text:'No flaky tests detected in the available runs.'}));return}\n const rows=model.flaky.map(item=>{\n const button=h('button',{class:'button',type:'button',text:item.title});\n button.addEventListener('click',()=>byId.has(item.testId)&&openTest(item.testId,button));\n const score=h('span',{},(item.score*100).toFixed(0)+'%',h('span',{class:'heat'},h('span',{style:'width:'+Math.round(item.score*100)+'%'})));\n return [button,item.file,item.project,score,item.runs,item.flakyRuns,item.fails,recentStrip(model.recent?.[item.testId])];\n });\n panel.appendChild(table(['Test','File','Project','Score','Runs','Flaky runs','Fails','Last 10'],rows));\n}\n";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const TRENDS_JS = `
|
|
2
|
+
function renderTrends(){
|
|
3
|
+
const panel=document.getElementById('tab-trends');clear(panel);panel.appendChild(h('h2',{text:'Trends'}));
|
|
4
|
+
const history=model.history||[];
|
|
5
|
+
if(history.length<2){panel.appendChild(h('p',{class:'empty',text:'Run the suite more times to see trends.'}));return}
|
|
6
|
+
const branches=[...new Set(history.map(item=>item.branch).filter(Boolean))].sort();
|
|
7
|
+
const select=h('select',{'aria-label':'Filter branch'},h('option',{value:'',text:'All branches'}));
|
|
8
|
+
for(const branch of branches)select.appendChild(h('option',{value:branch,text:branch}));
|
|
9
|
+
panel.appendChild(select);const content=h('div',{});panel.appendChild(content);
|
|
10
|
+
select.addEventListener('change',draw);
|
|
11
|
+
function draw(){
|
|
12
|
+
clear(content);const values=history.filter(item=>!select.value||item.branch===select.value);
|
|
13
|
+
const maxDuration=Math.max(1,...values.map(item=>item.durationMs));
|
|
14
|
+
const chart=s('svg',{class:'chart',viewBox:'0 0 800 190',role:'img','aria-label':'Pass rate and duration over runs'});
|
|
15
|
+
const coordinates=[];
|
|
16
|
+
values.forEach((item,index)=>{
|
|
17
|
+
const x=25+(values.length===1?375:index*750/(values.length-1));
|
|
18
|
+
const rate=item.summary.total?item.summary.passed/item.summary.total:0;
|
|
19
|
+
const y=150-120*rate;
|
|
20
|
+
coordinates.push([x,y]);
|
|
21
|
+
const barHeight=70*item.durationMs/maxDuration;
|
|
22
|
+
const bar=s('rect',{x:x-7,y:165-barHeight,width:14,height:barHeight});
|
|
23
|
+
bar.appendChild(s('title',{},item.runId+' · '+formatDuration(item.durationMs)));
|
|
24
|
+
chart.appendChild(bar);
|
|
25
|
+
});
|
|
26
|
+
const points=coordinates.map(([x,y])=>x+','+y).join(' ');
|
|
27
|
+
const area=s('polygon',{points:'25,165 '+points+' 775,165',class:'trend-area'});
|
|
28
|
+
chart.appendChild(area);chart.appendChild(s('polyline',{points,class:'trend-line'}));
|
|
29
|
+
values.forEach((item,index)=>{
|
|
30
|
+
const [x,y]=coordinates[index];const dot=s('circle',{cx:x,cy:y,r:4,class:'trend-dot'});
|
|
31
|
+
dot.appendChild(s('title',{},item.runId+' · '+item.status));
|
|
32
|
+
chart.appendChild(dot);
|
|
33
|
+
});
|
|
34
|
+
content.appendChild(chart);
|
|
35
|
+
const strip=h('div',{class:'run-strip','aria-label':'Run status history'});
|
|
36
|
+
for(const item of values)strip.appendChild(h('span',{class:item.status==='passed'?'passed':'failed',title:item.runId+' · '+item.status,'aria-label':item.runId+' '+item.status}));
|
|
37
|
+
content.appendChild(strip);
|
|
38
|
+
content.appendChild(table(['Run','Date','Branch','Status','Pass rate','Duration'],values.map(item=>[
|
|
39
|
+
item.runId+(item.runId===model.run.runId?' · current':''),item.startedAt,item.branch||'',item.status,
|
|
40
|
+
(item.summary.total?Math.round(100*item.summary.passed/item.summary.total):0)+'%',formatDuration(item.durationMs)
|
|
41
|
+
])));
|
|
42
|
+
}
|
|
43
|
+
draw();
|
|
44
|
+
}
|
|
45
|
+
function renderFlaky(){
|
|
46
|
+
const panel=document.getElementById('tab-flaky');clear(panel);panel.appendChild(h('h2',{text:'Flaky tests'}));
|
|
47
|
+
if(!model.flaky?.length){panel.appendChild(h('p',{class:'empty',text:'No flaky tests detected in the available runs.'}));return}
|
|
48
|
+
const rows=model.flaky.map(item=>{
|
|
49
|
+
const button=h('button',{class:'button',type:'button',text:item.title});
|
|
50
|
+
button.addEventListener('click',()=>byId.has(item.testId)&&openTest(item.testId,button));
|
|
51
|
+
const score=h('span',{},(item.score*100).toFixed(0)+'%',h('span',{class:'heat'},h('span',{style:'width:'+Math.round(item.score*100)+'%'})));
|
|
52
|
+
return [button,item.file,item.project,score,item.runs,item.flakyRuns,item.fails,recentStrip(model.recent?.[item.testId])];
|
|
53
|
+
});
|
|
54
|
+
panel.appendChild(table(['Test','File','Project','Score','Runs','Flaky runs','Fails','Last 10'],rows));
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
//# sourceMappingURL=trends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trends.js","sourceRoot":"","sources":["../../../src/template/js/trends.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDxB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const TOKENS: {
|
|
2
|
+
readonly dark: {
|
|
3
|
+
readonly bg: "#0b1020";
|
|
4
|
+
readonly surface: "#121a2e";
|
|
5
|
+
readonly 'surface-2': "#1a2440";
|
|
6
|
+
readonly border: "#2a3656";
|
|
7
|
+
readonly text: "#e8edf8";
|
|
8
|
+
readonly muted: "#aab7d4";
|
|
9
|
+
readonly accent: "#8ba7ff";
|
|
10
|
+
readonly 'accent-contrast': "#0b1020";
|
|
11
|
+
readonly passed: "#3ecf8e";
|
|
12
|
+
readonly failed: "#ff777e";
|
|
13
|
+
readonly flaky: "#ffc06e";
|
|
14
|
+
readonly skipped: "#aab7d4";
|
|
15
|
+
readonly info: "#6cc4ff";
|
|
16
|
+
readonly 'passed-bg': "rgba(62,207,142,.14)";
|
|
17
|
+
readonly 'failed-bg': "rgba(255,107,114,.14)";
|
|
18
|
+
readonly 'flaky-bg': "rgba(255,180,84,.14)";
|
|
19
|
+
readonly 'skipped-bg': "rgba(154,167,199,.14)";
|
|
20
|
+
readonly 'code-bg': "#0a0f1d";
|
|
21
|
+
readonly shadow: "0 8px 24px rgba(0,0,0,.35)";
|
|
22
|
+
};
|
|
23
|
+
readonly light: {
|
|
24
|
+
readonly bg: "#f4f6fb";
|
|
25
|
+
readonly surface: "#ffffff";
|
|
26
|
+
readonly 'surface-2': "#eef2fa";
|
|
27
|
+
readonly border: "#d8deec";
|
|
28
|
+
readonly text: "#131a2c";
|
|
29
|
+
readonly muted: "#56627f";
|
|
30
|
+
readonly accent: "#3954e6";
|
|
31
|
+
readonly 'accent-contrast': "#ffffff";
|
|
32
|
+
readonly passed: "#0b7a4f";
|
|
33
|
+
readonly failed: "#c62f3a";
|
|
34
|
+
readonly flaky: "#895000";
|
|
35
|
+
readonly skipped: "#56627f";
|
|
36
|
+
readonly info: "#0b6fa8";
|
|
37
|
+
readonly 'passed-bg': "rgba(11,122,79,.10)";
|
|
38
|
+
readonly 'failed-bg': "rgba(198,47,58,.10)";
|
|
39
|
+
readonly 'flaky-bg': "rgba(154,91,0,.10)";
|
|
40
|
+
readonly 'skipped-bg': "rgba(86,98,127,.10)";
|
|
41
|
+
readonly 'code-bg': "#f7f9fd";
|
|
42
|
+
readonly shadow: "0 6px 20px rgba(20,30,60,.10)";
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export declare function tokensToCss(theme: keyof typeof TOKENS): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const TOKENS = {
|
|
2
|
+
dark: {
|
|
3
|
+
bg: '#0b1020', surface: '#121a2e', 'surface-2': '#1a2440', border: '#2a3656', text: '#e8edf8', muted: '#aab7d4', accent: '#8ba7ff', 'accent-contrast': '#0b1020', passed: '#3ecf8e', failed: '#ff777e', flaky: '#ffc06e', skipped: '#aab7d4', info: '#6cc4ff', 'passed-bg': 'rgba(62,207,142,.14)', 'failed-bg': 'rgba(255,107,114,.14)', 'flaky-bg': 'rgba(255,180,84,.14)', 'skipped-bg': 'rgba(154,167,199,.14)', 'code-bg': '#0a0f1d', shadow: '0 8px 24px rgba(0,0,0,.35)',
|
|
4
|
+
},
|
|
5
|
+
light: {
|
|
6
|
+
bg: '#f4f6fb', surface: '#ffffff', 'surface-2': '#eef2fa', border: '#d8deec', text: '#131a2c', muted: '#56627f', accent: '#3954e6', 'accent-contrast': '#ffffff', passed: '#0b7a4f', failed: '#c62f3a', flaky: '#895000', skipped: '#56627f', info: '#0b6fa8', 'passed-bg': 'rgba(11,122,79,.10)', 'failed-bg': 'rgba(198,47,58,.10)', 'flaky-bg': 'rgba(154,91,0,.10)', 'skipped-bg': 'rgba(86,98,127,.10)', 'code-bg': '#f7f9fd', shadow: '0 6px 20px rgba(20,30,60,.10)',
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
export function tokensToCss(theme) {
|
|
10
|
+
return Object.entries(TOKENS[theme]).map(([name, value]) => `--${name}:${value};`).join('');
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/template/tokens.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE;QACJ,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,sBAAsB,EAAE,WAAW,EAAE,uBAAuB,EAAE,UAAU,EAAE,sBAAsB,EAAE,YAAY,EAAE,uBAAuB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,4BAA4B;KAChd;IACD,KAAK,EAAE;QACL,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,qBAAqB,EAAE,WAAW,EAAE,qBAAqB,EAAE,UAAU,EAAE,oBAAoB,EAAE,YAAY,EAAE,qBAAqB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,+BAA+B;KAC5c;CACO,CAAC;AAEX,MAAM,UAAU,WAAW,CAAC,KAA0B;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9F,CAAC"}
|
package/dist/template.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as clientlib from './clientlib.js';
|
|
2
|
+
import { buildDebugPacket, debugPacketMarkdown } from './debugpacket.js';
|
|
3
|
+
import { detectSignals } from './signals.js';
|
|
4
|
+
import { REPORT_CSS } from './template/css.js';
|
|
5
|
+
import { ICONS } from './template/icons.js';
|
|
6
|
+
import { CORE_JS } from './template/js/core.js';
|
|
7
|
+
import { TESTS_JS } from './template/js/tests.js';
|
|
8
|
+
import { PANEL_JS } from './template/js/panel.js';
|
|
9
|
+
import { FAILURES_JS } from './template/js/failures.js';
|
|
10
|
+
import { TRENDS_JS } from './template/js/trends.js';
|
|
11
|
+
import { RUN_JS } from './template/js/run.js';
|
|
12
|
+
import { PROJECT_JS } from './template/js/project.js';
|
|
13
|
+
import { HELP_JS } from './template/js/help.js';
|
|
14
|
+
export function buildStyles() { return REPORT_CSS; }
|
|
15
|
+
export function buildClientScript() {
|
|
16
|
+
const pure = Object.entries(clientlib).filter(([, value]) => typeof value === 'function');
|
|
17
|
+
return `(function(){'use strict';\n${pure.map(([name, fn]) => `const ${name}=(${fn.toString()});`).join('\n')}\nconst detectSignals=(${detectSignals.toString()});\nconst buildDebugPacket=(${buildDebugPacket.toString()});\nconst debugPacketMarkdown=(${debugPacketMarkdown.toString()});\nconst icons=${JSON.stringify(ICONS)};\ntry{${CORE_JS}${TESTS_JS}${PANEL_JS}${FAILURES_JS}${TRENDS_JS}${RUN_JS}${PROJECT_JS}${HELP_JS}\ninit()}catch(error){const banner=document.getElementById('lb-error');banner.hidden=false;banner.textContent='Report could not load: '+String(error)}})();`;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,MAAM,UAAU,WAAW,KAAa,OAAO,UAAU,CAAC,CAAC,CAAC;AAE5D,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC;IAC1F,OAAO,8BAA8B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,IAAI,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,aAAa,CAAC,QAAQ,EAAE,+BAA+B,gBAAgB,CAAC,QAAQ,EAAE,kCAAkC,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,6JAA6J,CAAC;AAClkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VERSION = "0.2.0";
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "playwright-logbook",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=20"
|
|
7
|
+
},
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"playwright-logbook": "dist/cli/bin.js",
|
|
19
|
+
"logbook": "dist/cli/bin.js"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"playwright",
|
|
26
|
+
"reporter",
|
|
27
|
+
"test-reporting",
|
|
28
|
+
"flaky-tests",
|
|
29
|
+
"ci",
|
|
30
|
+
"sharding"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -b && esbuild src/index.ts --bundle --platform=node --format=cjs --packages=external --outfile=dist/index.cjs",
|
|
37
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
|
|
38
|
+
"lint": "eslint .",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"demo": "npm run build && node scripts/make-demo.mjs",
|
|
41
|
+
"test:e2e": "npm run demo && playwright test --config=e2e/playwright.config.ts",
|
|
42
|
+
"shots": "npm run demo && node scripts/make-shots.mjs",
|
|
43
|
+
"check": "npm run lint && npm run typecheck && npm run build && npm test"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"commander": "^14.0.0",
|
|
47
|
+
"zod": "^4.1.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@playwright/test": ">=1.42"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@playwright/test": "^1.55.0",
|
|
54
|
+
"@types/node": "^24.0.0",
|
|
55
|
+
"esbuild": "^0.28.2",
|
|
56
|
+
"eslint": "^9.0.0",
|
|
57
|
+
"eslint-config-prettier": "^10.0.0",
|
|
58
|
+
"prettier": "^3.0.0",
|
|
59
|
+
"typescript": "^5.0.0",
|
|
60
|
+
"typescript-eslint": "^8.0.0",
|
|
61
|
+
"vitest": "^3.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|