reporting-labs 0.6.4 → 0.6.5

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/README.md CHANGED
@@ -606,7 +606,7 @@ Your Slack step can then read `results.json` for pass / fail counts and top fail
606
606
 
607
607
  ## Java teams
608
608
 
609
- The same report, from Java: `dev.reportinglabs` on Maven Central, for TestNG and JUnit 5, with zero-code add-ons for Selenium and REST Assured and a one-line add-on for Playwright for Java. Source: [reporting-labs-java](https://github.com/naveenautomationlabs/reporting-labs-java). Guides: [reportinglabs.dev/get-started/java](https://reportinglabs.dev/get-started/java).
609
+ The same report, from Java: `dev.reportinglabs` on Maven Central, for TestNG and JUnit 5, with zero-code add-ons for Selenium and REST Assured, a one-line add-on for Playwright for Java and a Cucumber JVM plugin (one row per scenario, Given/When/Then as steps). Source: [reporting-labs-java](https://github.com/naveenautomationlabs/reporting-labs-java). Guides: [reportinglabs.dev/get-started/java](https://reportinglabs.dev/get-started/java).
610
610
 
611
611
  ## Roadmap
612
612
 
@@ -226,6 +226,7 @@ a{color:var(--accent)}
226
226
  .step .t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
227
227
  .step .d{font:11px var(--mono);color:var(--ink-3)}
228
228
  .step.bad{color:var(--fail)} .step.bad .t{font-weight:500}
229
+ .step.skip .t,.step.skip .kw,.step.skip .d{color:var(--ink-3);font-style:italic}
229
230
  .step .e{font:12px var(--mono);color:var(--fail);padding:2px 0 6px 28px;white-space:pre-wrap}
230
231
  li.collapsed>ul{display:none}
231
232
  .att{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
@@ -1531,10 +1532,10 @@ function renderDetail(t){
1531
1532
  }
1532
1533
  function stepTree(steps, total){
1533
1534
  return h('ul',{class:'steps'}, steps.map(s=>{
1534
- const bad=!!s.error, kids=s.steps.length>0, pct=total?Math.min(100,s.duration/total*100):0;
1535
+ const bad=!!s.error, skip=s.status==='skipped', kids=s.steps.length>0, pct=total?Math.min(100,s.duration/total*100):0;
1535
1536
  const li=h('li',{class:kids&&!hasError(s)?'collapsed':''});
1536
- const row=h('div',{class:'step'+(bad?' bad':'')},
1537
- h('span',{class:'tw'}, kids? '▸' : ''), data.bdd?null:h('span',{class:'cat'},s.category), gherkin(s.title), total? h('span',{class:'tb',title:Math.round(pct)+'% of the test'}, h('i',{class:pct>=30?'slow':'',style:'width:'+Math.max(pct,s.duration>0?1.5:0)+'%'})) : null, h('span',{class:'d'},ms(s.duration)));
1537
+ const row=h('div',{class:'step'+(bad?' bad':'')+(skip?' skip':'')},
1538
+ h('span',{class:'tw'}, kids? '▸' : ''), data.bdd?null:h('span',{class:'cat'},s.category), gherkin(s.title), total&&!skip? h('span',{class:'tb',title:Math.round(pct)+'% of the test'}, h('i',{class:pct>=30?'slow':'',style:'width:'+Math.max(pct,s.duration>0?1.5:0)+'%'})) : null, h('span',{class:'d'},skip?'not run':ms(s.duration)));
1538
1539
  if(kids){ row.style.cursor='pointer'; row.addEventListener('click',()=>{li.classList.toggle('collapsed'); row.querySelector('.tw').textContent=li.classList.contains('collapsed')?'▸':'▾';}); if(!li.classList.contains('collapsed')) row.querySelector('.tw').textContent='▾'; }
1539
1540
  li.append(row); if(bad) li.append(h('div',{class:'e'},s.error)); if(kids) li.append(stepTree(s.steps, total));
1540
1541
  return li;
@@ -1593,7 +1594,7 @@ function bugModel(t){
1593
1594
  const r=t.results[t.results.length-1], e=r&&r.errors[0], x=e&&e.explain, msg=e?e.message:'';
1594
1595
  const ex=msg.match(/^\s*(Expected[^:\n]{0,40}):[ \t]*(.+)$/m), rc=msg.match(/^\s*((?:Received|Actual|But was)[^:\n]{0,40}):[ \t]*(.+)$/m);
1595
1596
  const si=sinceInfo(t);
1596
- const steps=[]; const walk=(list,depth)=>{ for(const st of list){ if(st.category==='hook'||/^Attach "/.test(st.title)||/^Worker Cleanup/.test(st.title)) continue; const user=st.category==='test.step'; if(user||depth===0) steps.push({title:st.title.replace(/^(Given|When|Then|And|But)\s+/,m=>m), failed:!!st.error, user}); if(user&&st.steps.length&&!st.steps.some(c=>c.category==='test.step')) continue; if(st.steps.length) walk(st.steps,depth+1); } };
1597
+ const steps=[]; const walk=(list,depth)=>{ for(const st of list){ if(st.category==='hook'||/^Attach "/.test(st.title)||/^Worker Cleanup/.test(st.title)) continue; const user=st.category==='test.step'; if(user||depth===0) steps.push({title:st.title.replace(/^(Given|When|Then|And|But)\s+/,m=>m)+(st.status==='skipped'?' (not run)':''), failed:!!st.error, user}); if(user&&st.steps.length&&!st.steps.some(c=>c.category==='test.step')) continue; if(st.steps.length) walk(st.steps,depth+1); } };
1597
1598
  if(r) walk(r.steps,0);
1598
1599
  const userSteps=steps.filter(s=>s.user); const repro=(userSteps.length?userSteps:steps).filter(s=>!/^Expect "/.test(s.title)||s.failed);
1599
1600
  const env=[]; if(data.options.project&&data.options.project.name) env.push(['Application', data.options.project.name+(data.options.project.version?' v'+data.options.project.version:'')]);
package/dist/template.js CHANGED
@@ -297,6 +297,7 @@ a{color:var(--accent)}
297
297
  .step .t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
298
298
  .step .d{font:11px var(--mono);color:var(--ink-3)}
299
299
  .step.bad{color:var(--fail)} .step.bad .t{font-weight:500}
300
+ .step.skip .t,.step.skip .kw,.step.skip .d{color:var(--ink-3);font-style:italic}
300
301
  .step .e{font:12px var(--mono);color:var(--fail);padding:2px 0 6px 28px;white-space:pre-wrap}
301
302
  li.collapsed>ul{display:none}
302
303
  .att{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
@@ -1597,10 +1598,10 @@ function renderDetail(t){
1597
1598
  }
1598
1599
  function stepTree(steps, total){
1599
1600
  return h('ul',{class:'steps'}, steps.map(s=>{
1600
- const bad=!!s.error, kids=s.steps.length>0, pct=total?Math.min(100,s.duration/total*100):0;
1601
+ const bad=!!s.error, skip=s.status==='skipped', kids=s.steps.length>0, pct=total?Math.min(100,s.duration/total*100):0;
1601
1602
  const li=h('li',{class:kids&&!hasError(s)?'collapsed':''});
1602
- const row=h('div',{class:'step'+(bad?' bad':'')},
1603
- h('span',{class:'tw'}, kids? '▸' : ''), data.bdd?null:h('span',{class:'cat'},s.category), gherkin(s.title), total? h('span',{class:'tb',title:Math.round(pct)+'% of the test'}, h('i',{class:pct>=30?'slow':'',style:'width:'+Math.max(pct,s.duration>0?1.5:0)+'%'})) : null, h('span',{class:'d'},ms(s.duration)));
1603
+ const row=h('div',{class:'step'+(bad?' bad':'')+(skip?' skip':'')},
1604
+ h('span',{class:'tw'}, kids? '▸' : ''), data.bdd?null:h('span',{class:'cat'},s.category), gherkin(s.title), total&&!skip? h('span',{class:'tb',title:Math.round(pct)+'% of the test'}, h('i',{class:pct>=30?'slow':'',style:'width:'+Math.max(pct,s.duration>0?1.5:0)+'%'})) : null, h('span',{class:'d'},skip?'not run':ms(s.duration)));
1604
1605
  if(kids){ row.style.cursor='pointer'; row.addEventListener('click',()=>{li.classList.toggle('collapsed'); row.querySelector('.tw').textContent=li.classList.contains('collapsed')?'▸':'▾';}); if(!li.classList.contains('collapsed')) row.querySelector('.tw').textContent='▾'; }
1605
1606
  li.append(row); if(bad) li.append(h('div',{class:'e'},s.error)); if(kids) li.append(stepTree(s.steps, total));
1606
1607
  return li;
@@ -1659,7 +1660,7 @@ function bugModel(t){
1659
1660
  const r=t.results[t.results.length-1], e=r&&r.errors[0], x=e&&e.explain, msg=e?e.message:'';
1660
1661
  const ex=msg.match(/^\s*(Expected[^:\n]{0,40}):[ \t]*(.+)$/m), rc=msg.match(/^\s*((?:Received|Actual|But was)[^:\n]{0,40}):[ \t]*(.+)$/m);
1661
1662
  const si=sinceInfo(t);
1662
- const steps=[]; const walk=(list,depth)=>{ for(const st of list){ if(st.category==='hook'||/^Attach "/.test(st.title)||/^Worker Cleanup/.test(st.title)) continue; const user=st.category==='test.step'; if(user||depth===0) steps.push({title:st.title.replace(/^(Given|When|Then|And|But)\s+/,m=>m), failed:!!st.error, user}); if(user&&st.steps.length&&!st.steps.some(c=>c.category==='test.step')) continue; if(st.steps.length) walk(st.steps,depth+1); } };
1663
+ const steps=[]; const walk=(list,depth)=>{ for(const st of list){ if(st.category==='hook'||/^Attach "/.test(st.title)||/^Worker Cleanup/.test(st.title)) continue; const user=st.category==='test.step'; if(user||depth===0) steps.push({title:st.title.replace(/^(Given|When|Then|And|But)\s+/,m=>m)+(st.status==='skipped'?' (not run)':''), failed:!!st.error, user}); if(user&&st.steps.length&&!st.steps.some(c=>c.category==='test.step')) continue; if(st.steps.length) walk(st.steps,depth+1); } };
1663
1664
  if(r) walk(r.steps,0);
1664
1665
  const userSteps=steps.filter(s=>s.user); const repro=(userSteps.length?userSteps:steps).filter(s=>!/^Expect "/.test(s.title)||s.failed);
1665
1666
  const env=[]; if(data.options.project&&data.options.project.name) env.push(['Application', data.options.project.name+(data.options.project.version?' v'+data.options.project.version:'')]);
package/dist/types.d.ts CHANGED
@@ -196,6 +196,8 @@ export interface StepData {
196
196
  category: string;
197
197
  duration: number;
198
198
  error?: string;
199
+ /** 'skipped' when the runner never executed it (a Cucumber step after a failed one) */
200
+ status?: 'skipped';
199
201
  steps: StepData[];
200
202
  }
201
203
  export interface AttachmentData {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reporting-labs",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "reportingLabs – beautiful, customizable single-file HTML test reports. One line of config. Playwright adapter included, more runners on the way.",
5
5
  "keywords": [
6
6
  "test-report",