Skip to content

Commit 682f9b4

Browse files
authored
Remove EnvelopesQuery, use hooks over props for app components (#374)
1 parent 76288ef commit 682f9b4

35 files changed

+528
-777
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
9+
### Changed
10+
- BREAKING CHANGE: Remove props from `<StatusesSummary/>`, `<ExecutionSummary/>` and `<SearchBar/>` components, use contexts for state ([#374](https://github.com/cucumber/react-components/pull/374))
11+
12+
### Removed
13+
- BREAKING CHANGE: Remove `EnvelopesQuery` and its React context ([#374](https://github.com/cucumber/react-components/pull/374))
914

1015
## [22.4.1] - 2025-03-30
1116
### Fixed

generate-fixtures.cjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ for (const ndjsonPath of glob.sync(
1313
const [suiteName, ...suffixes] = filename.split('.')
1414
const content = fs.readFileSync(ndjsonPath, { encoding: 'utf-8' })
1515
const asTs = `// Generated file. Do not edit.
16-
export default [${content.split('\n').join(',')}]
16+
import { Envelope } from '@cucumber/messages'
17+
18+
export default [${content.split('\n').join(',')}] as ReadonlyArray<Envelope>
1719
`
1820
const targetPath = `acceptance/${suiteName}/${suiteName}.${suffixes
1921
.filter((s) => s !== 'ndjson')

package-lock.json

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

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
"pretty-quick-staged": "pretty-quick --staged"
2626
},
2727
"dependencies": {
28-
"@cucumber/gherkin-utils": "9.0.0",
29-
"@cucumber/messages": "25.0.1",
30-
"@cucumber/query": "12.2.0",
31-
"@cucumber/tag-expressions": "6.1.0",
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",
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,11 +55,11 @@
5555
"react-dom": "~18"
5656
},
5757
"devDependencies": {
58-
"@cucumber/compatibility-kit": "16.1.0",
59-
"@cucumber/fake-cucumber": "16.5.0",
60-
"@cucumber/gherkin": "28.0.0",
61-
"@cucumber/gherkin-streams": "5.0.1",
62-
"@cucumber/message-streams": "4.0.1",
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",
62+
"@cucumber/message-streams": "^4.0.1",
6363
"@eslint/compat": "^1.2.7",
6464
"@eslint/eslintrc": "^3.2.0",
6565
"@eslint/js": "^9.20.0",

src/EnvelopesQueryContext.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/acceptance.spec.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { pipeline, Writable } from 'stream'
1717
import { promisify } from 'util'
1818

1919
import { CucumberQueryStream, render } from '../test-utils/index.js'
20-
import { EnvelopesQuery } from './EnvelopesQueryContext.js'
2120
import { components } from './index.js'
2221

2322
describe('acceptance tests', function () {
@@ -37,7 +36,6 @@ describe('acceptance tests', function () {
3736
})
3837
const gherkinQuery = new GherkinQuery()
3938
const cucumberQuery = new CucumberQuery()
40-
const envelopesQuery = new EnvelopesQuery()
4139

4240
const cucumberQueryStream = new CucumberQueryStream(cucumberQuery)
4341
await runCucumber(supportCode, gherkinStream, gherkinQuery, cucumberQueryStream)
@@ -46,7 +44,6 @@ describe('acceptance tests', function () {
4644
<components.app.QueriesWrapper
4745
gherkinQuery={gherkinQuery}
4846
cucumberQuery={cucumberQuery}
49-
envelopesQuery={envelopesQuery}
5047
>
5148
<components.app.GherkinDocumentList
5249
gherkinDocuments={gherkinQuery.getGherkinDocuments()}
@@ -73,7 +70,6 @@ describe('acceptance tests', function () {
7370
it(`can render ${messageFile}`, async () => {
7471
const gherkinQuery = new GherkinQuery()
7572
const cucumberQuery = new CucumberQuery()
76-
const envelopesQuery = new EnvelopesQuery()
7773

7874
const messageStream = new NdjsonToMessageStream()
7975

@@ -89,18 +85,13 @@ describe('acceptance tests', function () {
8985
) {
9086
gherkinQuery.update(envelope)
9187
cucumberQuery.update(envelope)
92-
envelopesQuery.update(envelope)
9388
callback()
9489
},
9590
})
9691
)
9792

9893
const { container } = render(
99-
<components.app.QueriesWrapper
100-
gherkinQuery={gherkinQuery}
101-
cucumberQuery={cucumberQuery}
102-
envelopesQuery={envelopesQuery}
103-
>
94+
<components.app.QueriesWrapper gherkinQuery={gherkinQuery} cucumberQuery={cucumberQuery}>
10495
<components.app.GherkinDocumentList
10596
gherkinDocuments={gherkinQuery.getGherkinDocuments()}
10697
/>

src/components/app/EnvelopesWrapper.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import * as messages from '@cucumber/messages'
33
import { Query as CucumberQuery } from '@cucumber/query'
44
import React, { FunctionComponent, PropsWithChildren, useMemo } from 'react'
55

6-
import { EnvelopesQuery } from '../../EnvelopesQueryContext.js'
76
import { QueriesWrapper } from './QueriesWrapper.js'
87

98
interface IProps {
@@ -14,23 +13,17 @@ export const EnvelopesWrapper: FunctionComponent<PropsWithChildren<IProps>> = ({
1413
envelopes,
1514
children,
1615
}) => {
17-
const { gherkinQuery, cucumberQuery, envelopesQuery } = useMemo(() => {
16+
const { gherkinQuery, cucumberQuery } = useMemo(() => {
1817
const gherkinQuery = new GherkinQuery()
1918
const cucumberQuery = new CucumberQuery()
20-
const envelopesQuery = new EnvelopesQuery()
2119
for (const envelope of envelopes) {
2220
gherkinQuery.update(envelope)
2321
cucumberQuery.update(envelope)
24-
envelopesQuery.update(envelope)
2522
}
26-
return { gherkinQuery, cucumberQuery, envelopesQuery }
23+
return { gherkinQuery, cucumberQuery }
2724
}, [envelopes])
2825
return (
29-
<QueriesWrapper
30-
gherkinQuery={gherkinQuery}
31-
cucumberQuery={cucumberQuery}
32-
envelopesQuery={envelopesQuery}
33-
>
26+
<QueriesWrapper gherkinQuery={gherkinQuery} cucumberQuery={cucumberQuery}>
3427
{children}
3528
</QueriesWrapper>
3629
)
Lines changed: 34 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,54 @@
1-
import { TestStepResultStatus, TimeConversion } from '@cucumber/messages'
1+
import { Meta } from '@cucumber/messages'
22
import { render } from '@testing-library/react'
33
import { expect } from 'chai'
4-
import { add, addMilliseconds } from 'date-fns'
54
import React from 'react'
65

7-
import { makeEmptyScenarioCountsByStatus } from '../../countScenariosByStatuses.js'
8-
import { ExecutionSummary, IExecutionSummaryProps } from './ExecutionSummary.js'
9-
10-
const startDate = new Date(1639753096000)
11-
const finishDate = new Date(1639753197000)
12-
13-
const scenarioCountByStatus = {
14-
...makeEmptyScenarioCountsByStatus(),
15-
...{
16-
[TestStepResultStatus.PASSED]: 100,
17-
[TestStepResultStatus.FAILED]: 3,
18-
[TestStepResultStatus.UNDEFINED]: 1,
19-
},
20-
}
21-
22-
const DEFAULT_PROPS: IExecutionSummaryProps = {
23-
scenarioCountByStatus,
24-
totalScenarioCount: 104,
25-
testRunStarted: {
26-
timestamp: TimeConversion.millisecondsSinceEpochToTimestamp(startDate.getTime()),
27-
},
28-
testRunFinished: {
29-
timestamp: TimeConversion.millisecondsSinceEpochToTimestamp(finishDate.getTime()),
30-
success: false,
31-
},
32-
meta: {
33-
protocolVersion: '17.1.1',
34-
implementation: { version: '8.0.0-rc.1', name: 'cucumber-js' },
35-
cpu: { name: 'x64' },
36-
os: { name: 'linux', version: '5.11.0-1022-azure' },
37-
runtime: { name: 'node.js', version: '16.13.1' },
38-
ci: {
39-
name: 'GitHub Actions',
40-
url: 'https://github.com/cucumber/cucumber-js/actions/runs/1592557391',
41-
buildNumber: '1592557391',
42-
git: {
43-
revision: 'b53d820504b31c8e4d44234dc5eaa58d6b7fdd4c',
44-
remote: 'https://github.com/cucumber/cucumber-js.git',
45-
branch: 'main',
46-
},
6+
import examplesTablesFeature from '../../../acceptance/examples-tables/examples-tables.feature.js'
7+
import { EnvelopesWrapper } from './EnvelopesWrapper.js'
8+
import { ExecutionSummary } from './ExecutionSummary.js'
9+
10+
const meta: Meta = {
11+
protocolVersion: '17.1.1',
12+
implementation: { version: '8.0.0-rc.1', name: 'cucumber-js' },
13+
cpu: { name: 'x64' },
14+
os: { name: 'linux', version: '5.11.0-1022-azure' },
15+
runtime: { name: 'node.js', version: '16.13.1' },
16+
ci: {
17+
name: 'GitHub Actions',
18+
url: 'https://github.com/cucumber/cucumber-js/actions/runs/1592557391',
19+
buildNumber: '1592557391',
20+
git: {
21+
revision: 'b53d820504b31c8e4d44234dc5eaa58d6b7fdd4c',
22+
remote: 'https://github.com/cucumber/cucumber-js.git',
23+
branch: 'main',
4724
},
4825
},
4926
}
5027

5128
describe('ExecutionSummary', () => {
52-
describe('last run date/time', () => {
53-
const examples: [text: string, referenceDate: Date][] = [
54-
['1 hour ago', add(startDate, { hours: 1 })],
55-
['3 hours ago', add(startDate, { hours: 3, minutes: 24, seconds: 18 })],
56-
['1 day ago', add(startDate, { days: 1, hours: 3, minutes: 24, seconds: 18 })],
57-
['15 days ago', add(startDate, { weeks: 2, days: 1 })],
58-
]
59-
60-
for (const [text, referenceDate] of examples) {
61-
it(`should render correctly for ${text}`, () => {
62-
const { getByText } = render(
63-
<ExecutionSummary {...DEFAULT_PROPS} referenceDate={referenceDate} />
64-
)
65-
66-
expect(getByText(text)).to.be.visible
67-
expect(getByText('last run')).to.be.visible
68-
})
69-
}
70-
})
71-
72-
describe('run duration', () => {
73-
const examples: [text: string, finishDate: Date][] = [
74-
['1 hour 45 minutes 23 seconds', add(startDate, { hours: 1, minutes: 45, seconds: 23 })],
75-
['12 minutes 15 seconds', add(startDate, { minutes: 12, seconds: 15 })],
76-
['10 seconds', add(startDate, { seconds: 10.01 })],
77-
['9.88 seconds', addMilliseconds(startDate, 9876)],
78-
['6.54 seconds', addMilliseconds(startDate, 6543)],
79-
]
80-
81-
for (const [text, finishDate] of examples) {
82-
it(`should render correctly for ${text}`, () => {
83-
const { getByText } = render(
84-
<ExecutionSummary
85-
{...DEFAULT_PROPS}
86-
testRunFinished={{
87-
timestamp: TimeConversion.millisecondsSinceEpochToTimestamp(finishDate.getTime()),
88-
success: false,
89-
}}
90-
/>
91-
)
92-
93-
expect(getByText(text)).to.be.visible
94-
expect(getByText('duration')).to.be.visible
95-
})
96-
}
97-
})
98-
99-
describe('passed rate', () => {
100-
const examples: [passed: number, total: number, percentage: string][] = [
101-
[13, 45, '29%'],
102-
[5, 45, '11%'],
103-
[45, 45, '100%'],
104-
[0, 45, '0%'],
105-
[0, 0, '0%'],
106-
]
107-
108-
for (const [passed, total, percentage] of examples) {
109-
it(`should render correctly for ${percentage} passed`, () => {
110-
const { getByText } = render(
111-
<ExecutionSummary
112-
{...DEFAULT_PROPS}
113-
scenarioCountByStatus={{
114-
...makeEmptyScenarioCountsByStatus(),
115-
[TestStepResultStatus.PASSED]: passed,
116-
}}
117-
totalScenarioCount={total}
118-
/>
119-
)
120-
121-
expect(getByText(`${percentage} passed`)).to.be.visible
122-
expect(getByText(`${total} executed`)).to.be.visible
123-
})
124-
}
125-
})
29+
const envelopes = [...examplesTablesFeature, { meta }]
12630

12731
describe('meta', () => {
12832
it('should include the implementation name and version', () => {
129-
const { getByText } = render(<ExecutionSummary {...DEFAULT_PROPS} />)
33+
const { getByText } = render(
34+
<EnvelopesWrapper envelopes={envelopes}>
35+
<ExecutionSummary />
36+
</EnvelopesWrapper>
37+
)
13038

13139
expect(getByText('cucumber-js 8.0.0-rc.1')).to.be.visible
13240
})
41+
13342
it('should include the job link', () => {
134-
const { getByText } = render(<ExecutionSummary {...DEFAULT_PROPS} />)
135-
const jobLinkElement = getByText(DEFAULT_PROPS.meta?.ci?.buildNumber as string)
43+
const { getByText } = render(
44+
<EnvelopesWrapper envelopes={envelopes}>
45+
<ExecutionSummary />
46+
</EnvelopesWrapper>
47+
)
48+
49+
const jobLinkElement = getByText(meta?.ci?.buildNumber as string)
13650
expect(jobLinkElement).to.be.visible
137-
expect(jobLinkElement.getAttribute('href')).to.eq(DEFAULT_PROPS.meta?.ci?.url)
51+
expect(jobLinkElement.getAttribute('href')).to.eq(meta?.ci?.url)
13852
})
13953
})
14054
})

0 commit comments

Comments
 (0)