Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
56162d7
Added hook for timeline data
MuhammadTalha57 Jul 4, 2026
c9151b4
Created React component for Timeline
MuhammadTalha57 Jul 4, 2026
8fd908d
Added tests for Timeline component
MuhammadTalha57 Jul 4, 2026
d8a739f
Updated changelog
MuhammadTalha57 Jul 4, 2026
2ce987f
Added Tabs in Report to switch between two formats
MuhammadTalha57 Jul 6, 2026
3b0e233
style: fix lint formatting issues
MuhammadTalha57 Jul 7, 2026
814609c
Added sample parallel run envelope
MuhammadTalha57 Jul 7, 2026
f417dc6
removed old parallel-run file (locally generated)
MuhammadTalha57 Jul 9, 2026
968da1e
Reimplemented Timeline component using vis-timeline
MuhammadTalha57 Jul 9, 2026
b034d68
Added Tooltip
MuhammadTalha57 Jul 25, 2026
424c17a
Implemented Basic Layout of Timeline
MuhammadTalha57 Jul 26, 2026
fa77e0f
Separated Timeline Axis Component
MuhammadTalha57 Aug 1, 2026
87e7746
Added Panning
MuhammadTalha57 Aug 3, 2026
052a4f7
Fixed Panning and Zoom
MuhammadTalha57 Aug 3, 2026
ecc624c
Fixed useRef issue
MuhammadTalha57 Aug 4, 2026
92d59eb
Cleanup
MuhammadTalha57 Aug 4, 2026
cfc6c14
Refactored Timeline Bar
MuhammadTalha57 Aug 4, 2026
1a6bdfc
Refactored useTimeline hook
MuhammadTalha57 Aug 4, 2026
5eae00b
Implemented items bucket
MuhammadTalha57 Aug 4, 2026
53a9236
Uninstalled vis-data and vis-timeline
MuhammadTalha57 Aug 4, 2026
8cb7d23
Resolved Merge Conflicts
MuhammadTalha57 Aug 4, 2026
e1edcb6
Fixed formatting
MuhammadTalha57 Aug 4, 2026
05b434c
Added useMemo for selectedItem and cleanup
MuhammadTalha57 Aug 4, 2026
b123a24
Fixed formatting
MuhammadTalha57 Aug 4, 2026
2bcac70
Fixed axis tick and item detail UI
MuhammadTalha57 Aug 4, 2026
b7975c8
Removed tooltip overlay arrow
MuhammadTalha57 Aug 4, 2026
db9cdb0
fix: correct bucket duration, merge condition, and minimum bar width …
MuhammadTalha57 Aug 13, 2026
dbfed16
Fixed merge condition check when mergin with right item
MuhammadTalha57 Aug 17, 2026
c619843
Added message for no executed/filtered scenarios
MuhammadTalha57 Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,3 +583,7 @@ to rebuild them every time the envelope list is updated. Use this instead of `<W
[4.1.1]: https://github.com/cucumber/cucumber-react/compare/v4.0.0...v4.1.1
[4.0.0]: https://github.com/cucumber/cucumber-react/compare/v3.3.0...v4.0.0
[3.3.0]: https://github.com/cucumber/cucumber-react/compare/v3.2.0...v3.3.0

## [Unreleased]
### Added
- Added `<Timeline/>` component showing scenario execution over time grouped by worker ([#126](https://github.com/cucumber/react-components/issues/126))
28 changes: 16 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions src/components/app/Report.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@use '../../styles/theming';

.layout {
> section:not(:last-child) {
margin-bottom: 1.5em;
Expand All @@ -8,3 +10,37 @@
font-size: 1.25em;
margin: 1em 0;
}

.tabList {
display: flex;
gap: 0.25em;
border-bottom: 1px solid theming.$panelAccentColor;
margin-bottom: 1em;
}

.tab {
padding: 0.5em 1em;
border-bottom: 2px solid transparent;
color: theming.$panelTextColor;
cursor: pointer;
outline: none;

&[data-hovered] {
background-color: theming.$panelBackgroundColor;
}

&[data-selected] {
border-bottom-color: theming.$anchorColor;
color: theming.$anchorColor;
font-weight: 600;
}

&[data-focus-visible] {
outline: 2px solid theming.$anchorColor;
outline-offset: 2px;
}
}

.tabPanel {
outline: none;
}
22 changes: 20 additions & 2 deletions src/components/app/Report.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { FC } from 'react'
import { Tab, TabList, TabPanel, TabPanels, Tabs } from 'react-aria-components'

import { ExecutionSummary } from './ExecutionSummary.js'
import { FilteredDocuments } from './FilteredDocuments.js'
import styles from './Report.module.scss'
import { SearchBar } from './SearchBar.js'
import { TestRunHooks } from './TestRunHooks.js'
import { Timeline } from './Timeline.js'

export const Report: FC = () => {
return (
Expand All @@ -14,8 +16,24 @@ export const Report: FC = () => {
<SearchBar />
</section>
<section>
<h2 className={styles.heading}>Scenarios</h2>
<FilteredDocuments />
<Tabs className={styles.tabs}>
<TabList aria-label="Report views" className={styles.tabList}>
<Tab id="scenarios" className={styles.tab}>
Scenarios
</Tab>
<Tab id="timeline" className={styles.tab}>
Timeline
</Tab>
</TabList>
<TabPanels>
<TabPanel id="scenarios" className={styles.tabPanel}>
<FilteredDocuments />
</TabPanel>
<TabPanel id="timeline" className={styles.tabPanel}>
<Timeline />
</TabPanel>
</TabPanels>
</Tabs>
</section>
<section>
<h2 className={styles.heading}>Hooks</h2>
Expand Down
227 changes: 227 additions & 0 deletions src/components/app/Timeline.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
@use '../../styles/statuses';
@use '../../styles/theming';
@use 'sass:color';

.empty {
font-style: italic;
}

.timelineWrapper {
display: flex;
flex-direction: column;
padding: 1px;
}

.timelineRow {
width: 100%;
display: grid;
grid-template-columns: 1fr minmax(0, 4fr);
gap: 1px;
border: 1px solid theming.$panelAccentColor;
border-top: none;
}

.timelineRow:first-child {
border-top: 1px solid theming.$panelAccentColor;
}

.cell {
height: 3em;
}

.cell:first-child {
border-right: 1px solid theming.$panelAccentColor;
}

.leftCell {
display: flex;
align-items: center;
padding-left: 0.5em;
font-family: inherit;
}

// Timeline Bar Styles

.timelineBarWrapper {
display: flex;
overflow: hidden;
align-items: center;
position: sticky; // Allows setting timelineBar position: absolute
}

.timelineBar {
height: 80%;
border-radius: 0.333em;
border: none;
padding: 0;
box-sizing: border-box;
flex: none;
position: absolute;
}

@each $name, $color in statuses.$statusColors {
.timelineBar[data-status='#{$name}'] {
background-color: color.adjust($color, $alpha: -0.666);
border-color: $color;

&:hover {
outline: 1px solid $color;
}

&.selected {
outline: 1px solid $color
}
}
}

// Tooltip Styles

.icon {
padding-top: 0.35em;
padding-left: 0.5em;
padding-right: 0.5em;
}

// Tooltip card
:global(.react-aria-Tooltip) {
display: flex;
flex-direction: column;
overflow: hidden;
background-color: theming.$panelBackgroundColor;
color: theming.$panelTextColor;
border: 1px solid theming.$panelAccentColor;
border-radius: 0.25em;
padding: 0.4em 0.6em;
font-size: inherit;
font-family: inherit;
align-items: center;
gap: 0.4em;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
max-width: 20em;
margin-bottom: 0.7em;
}

.tooltipBtn {
border: none;
background: none;
}

// Arrow styling
:global(.react-aria-Tooltip) svg {
fill: theming.$exampleNumberColor;
stroke: theming.$panelAccentColor;
stroke-width: 1px;
}

// Axis Styles

.axisUnit {
font-size: 0.65em;
text-transform: uppercase;
letter-spacing: 0.05em;
color: theming.$exampleNumberColor;
opacity: 0.9;
}

.axisRuler {
position: relative;
overflow: hidden;
cursor: grab;
user-select: none;
border: none;
background-color: inherit;
padding: 0;
margin: 0;
}

.axisRuler:active {
cursor: grabbing;
}

.minorTick {
position: absolute;
bottom: 0;
width: 2px;
height: 30%;
background-color: theming.$panelAccentColor;
pointer-events: none;
}

.majorTick {
position: absolute;
bottom: 0;
width: 2px;
height: 55%;
background-color: theming.$exampleNumberColor;
pointer-events: none;
}

.tickLabel {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
font-size: 0.6em;
line-height: 1.5;
white-space: nowrap;
color: theming.$panelTextColor;
opacity: 0.75;
pointer-events: none;
}


// Timeline Bar Detail Styles

.detail {
position: relative;
padding: 1em;
background-color: theming.$panelBackgroundColor;
color: theming.$panelTextColor;
border: 1px solid theming.$panelAccentColor;
border-radius: 0.25em;
}

.detailClose {
position: absolute;
top: 0.5em;
right: 0.5em;
padding: 0.25em;
background: none;
border: none;
cursor: pointer;
color: inherit;
}

.detailTitle {
display: flex;
align-items: center;
gap: 0.4em;
margin: 0 0 0.25em;
font-size: 1.1em;

svg {
height: 1em;
}
}

.detailFeature {
margin: 0 0 0.5em;
opacity: 0.75;
}

.detailMeta {
display: flex;
flex-wrap: wrap;
gap: 1em;
margin: 0.75em 0 0;

dt {
font-size: 0.75em;
text-transform: uppercase;
opacity: 0.75;
}

dd {
margin: 0;
}
}
Loading