Skip to content

Commit 87b7106

Browse files
authored
Render a more test case-centric report (#396)
1 parent fdaf2c5 commit 87b7106

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+929
-1279
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99
### Added
10+
- Include duration for each test step ([#396](https://github.com/cucumber/react-components/pull/396))
1011
- Include pass rate in execution summary ([#397](https://github.com/cucumber/react-components/pull/397))
1112

13+
### Changed
14+
- Render a more test case-centric report ([#396](https://github.com/cucumber/react-components/pull/396))
15+
16+
### Removed
17+
- BREAKING CHANGE: Remove defunct scenario/step components `<ExamplesTable/>`, `<GherkinStep/>`, `<GherkinSteps/>`, `<HookStep/>`, `<HookSteps/>`, `<StepItem/>` and their corresponding `CustomRenderingSupport` properties ([#396](https://github.com/cucumber/react-components/pull/396))
18+
- BREAKING CHANGE: Remove defunct `<UriProvider/>` component and underlying context ([#396](https://github.com/cucumber/react-components/pull/396))
19+
- BREAKING CHANGE: Remove `<MDG/>` component in favour of using standard Gherkin components for Markdown documents ([#396](https://github.com/cucumber/react-components/pull/396))
20+
1221
## [23.2.0] - 2025-08-07
1322
### Changed
1423
- Applied URI-based sorting for the displayed Gherkin documents ([#394](https://github.com/cucumber/react-components/pull/394))

generate-fixtures.cjs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ for (const ndjsonPath of glob.sync(
1010
'node_modules/@cucumber/compatibility-kit/features/**/*.ndjson'
1111
)) {
1212
const filename = path.basename(ndjsonPath)
13-
const [suiteName, ...suffixes] = filename.split('.')
13+
const [suiteName] = filename.split('.')
1414
const content = fs.readFileSync(ndjsonPath, { encoding: 'utf-8' })
1515
const asTs = `// Generated file. Do not edit.
1616
import { Envelope } from '@cucumber/messages'
1717
1818
export default [${content.split('\n').join(',')}] as ReadonlyArray<Envelope>
1919
`
20-
const targetPath = `acceptance/${suiteName}/${suiteName}.${suffixes
21-
.filter((s) => s !== 'ndjson')
22-
.join('.')}.ts`
20+
const targetPath = `acceptance/${suiteName}/${suiteName}.ts`
2321
fs.mkdirSync(`acceptance/${suiteName}`, { recursive: true })
2422
fs.writeFileSync(targetPath, asTs, { encoding: 'utf-8' })
2523
}

package-lock.json

Lines changed: 117 additions & 87 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
"lint": "eslint --max-warnings 0 src test-utils && prettier --check src test-utils"
2626
},
2727
"dependencies": {
28-
"@cucumber/gherkin-utils": "9.2.0",
29-
"@cucumber/messages": "27.2.0",
30-
"@cucumber/query": "13.2.0",
31-
"@cucumber/tag-expressions": "6.1.2",
28+
"@cucumber/gherkin-utils": "10.0.0",
29+
"@cucumber/messages": "29.0.1",
30+
"@cucumber/query": "14.0.1",
31+
"@cucumber/tag-expressions": "6.2.0",
3232
"@fortawesome/fontawesome-svg-core": "6.2.1",
3333
"@fortawesome/free-solid-svg-icons": "6.2.1",
3434
"@fortawesome/react-fontawesome": "0.2.0",
@@ -55,10 +55,10 @@
5555
"react-dom": "~18"
5656
},
5757
"devDependencies": {
58-
"@cucumber/compatibility-kit": "^18.0.2",
59-
"@cucumber/fake-cucumber": "^18.0.0",
60-
"@cucumber/gherkin": "^32.0.1",
61-
"@cucumber/gherkin-streams": "^5.0.1",
58+
"@cucumber/compatibility-kit": "^22.0.1",
59+
"@cucumber/fake-cucumber": "^18.1.0",
60+
"@cucumber/gherkin": "^35.0.0",
61+
"@cucumber/gherkin-streams": "^6.0.0",
6262
"@cucumber/message-streams": "^4.0.1",
6363
"@eslint/compat": "^1.2.7",
6464
"@eslint/eslintrc": "^3.2.0",

screenshots/examples-tables.png

455 KB
Loading

src/UriContext.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.
File renamed without changes.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { TestStepResultStatus } from '@cucumber/messages'
2+
import { faChevronRight } from '@fortawesome/free-solid-svg-icons'
3+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4+
import React, { FC, ReactNode } from 'react'
5+
import {
6+
Accordion,
7+
AccordionItem,
8+
AccordionItemButton,
9+
AccordionItemHeading,
10+
AccordionItemPanel,
11+
} from 'react-accessible-accordion'
12+
13+
import { StatusIcon } from '../gherkin/index.js'
14+
import styles from './DocumentAccordion.module.scss'
15+
16+
const idByUri = new Map<string, string>()
17+
function getIdByUri(uri: string): string {
18+
if (!idByUri.has(uri)) {
19+
idByUri.set(uri, crypto.randomUUID())
20+
}
21+
return idByUri.get(uri) as string
22+
}
23+
24+
interface DocumentAccordionProps {
25+
expanded: ReadonlyArray<string>
26+
children: ReactNode
27+
}
28+
29+
interface DocumentAccordionItemProps {
30+
status: TestStepResultStatus
31+
uri: string
32+
children: ReactNode
33+
}
34+
35+
export const DocumentAccordion: FC<DocumentAccordionProps> = ({ expanded, children }) => {
36+
const preExpand = expanded.map((uri) => getIdByUri(uri))
37+
return (
38+
<Accordion
39+
allowMultipleExpanded={true}
40+
allowZeroExpanded={true}
41+
preExpanded={preExpand}
42+
className={styles.accordion}
43+
>
44+
{children}
45+
</Accordion>
46+
)
47+
}
48+
49+
export const DocumentAccordionItem: FC<DocumentAccordionItemProps> = ({
50+
status,
51+
uri,
52+
children,
53+
}) => {
54+
const id = getIdByUri(uri)
55+
return (
56+
<AccordionItem uuid={id} className={styles.accordionItem}>
57+
<AccordionItemHeading>
58+
<AccordionItemButton className={styles.accordionButton}>
59+
<FontAwesomeIcon
60+
className={styles.accordionChevron}
61+
aria-hidden="true"
62+
icon={faChevronRight}
63+
/>
64+
<span className={styles.icon}>
65+
<StatusIcon status={status} />
66+
</span>
67+
<span>{uri}</span>
68+
</AccordionItemButton>
69+
</AccordionItemHeading>
70+
<AccordionItemPanel className={styles.accordionPanel}>{children}</AccordionItemPanel>
71+
</AccordionItem>
72+
)
73+
}

src/components/app/ExecutionSummary.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { expect } from 'chai'
55
import React from 'react'
66
import sinon from 'sinon'
77

8-
import examplesTablesFeature from '../../../acceptance/examples-tables/examples-tables.feature.js'
8+
import examplesTablesFeature from '../../../acceptance/examples-tables/examples-tables.js'
99
import { EnvelopesProvider } from './EnvelopesProvider.js'
1010
import { ExecutionSummary } from './ExecutionSummary.js'
1111

src/components/app/ExecutionSummary.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { TestRunFinished, TestRunStarted, TimeConversion } from '@cucumber/messa
33
import { Story } from '@ladle/react'
44
import React from 'react'
55

6-
import examplesTablesFeature from '../../../acceptance/examples-tables/examples-tables.feature.js'
6+
import examplesTablesFeature from '../../../acceptance/examples-tables/examples-tables.js'
77
import { EnvelopesProvider } from './EnvelopesProvider.js'
88
import { ExecutionSummary } from './ExecutionSummary.js'
99

0 commit comments

Comments
 (0)