Skip to content

Commit

Permalink
feat: provide worker id to envelope message (#2085)
Browse files Browse the repository at this point in the history
  • Loading branch information
epszaw authored Nov 14, 2022
1 parent 1d5d345 commit 3bd70c8
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 70 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) on how to contribute to Cucumber.

## [Unreleased]
## Changed
### Changed
- Add `workerId` property to `testCaseStarted` message ([#2085](https://github.com/cucumber/cucumber-js/pull/2085))
- Handle stack traces without V8-specific modification ([#2119](https://github.com/cucumber/cucumber-js/pull/2119))

## [8.7.0] - 2022-10-17
Expand Down
62 changes: 48 additions & 14 deletions docs/parallel.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ The number you provide is the number of workers that will run scenarios in paral

Each worker receives the following env variables (as well as a copy of `process.env` from the coordinator process):

* `CUCUMBER_PARALLEL` - set to 'true'
* `CUCUMBER_TOTAL_WORKERS` - set to the number of workers
* `CUCUMBER_WORKER_ID` - ID for worker ('0', '1', '2', etc.)
- `CUCUMBER_PARALLEL` - set to 'true'
- `CUCUMBER_TOTAL_WORKERS` - set to the number of workers
- `CUCUMBER_WORKER_ID` - ID for worker ('0', '1', '2', etc.)

### Timing

Expand All @@ -32,36 +32,70 @@ When using parallel mode, any `BeforeAll` and `AfterAll` hooks you have defined
If you would like to prevent specific sets of scenarios from running in parallel you can use `setParallelCanAssign`.

Example:

```javascript
setParallelCanAssign(function(pickleInQuestion, picklesInProgress) {
setParallelCanAssign(function (pickleInQuestion, picklesInProgress) {
// Only one pickle with the word example in the name can run at a time
if (pickleInQuestion.name.includes("example")) {
return picklesInProgress.every(p => !p.name.includes("example"));
if (pickleInQuestion.name.includes('example')) {
return picklesInProgress.every((p) => !p.name.includes('example'))
}
// No other restrictions
return true;
return true
})
```

For convenience, the following helpers exist to build a `canAssignFn`:

```javascript
import { setParallelCanAssign, parallelCanAssignHelpers } from '@cucumber/cucumber'
import {
setParallelCanAssign,
parallelCanAssignHelpers,
} from '@cucumber/cucumber'

const { atMostOnePicklePerTag } = parallelCanAssignHelpers
const myTagRule = atMostOnePicklePerTag(["@tag1", "@tag2"]);
const myTagRule = atMostOnePicklePerTag(['@tag1', '@tag2'])

// Only one pickle with @tag1 can run at a time
// AND only one pickle with @tag2 can run at a time
setParallelCanAssign(myTagRule)

// If you want to join a tag rule with other rules you can compose them like so:
const myCustomRule = function(pickleInQuestion, picklesInProgress) {
const myCustomRule = function (pickleInQuestion, picklesInProgress) {
// ...
};
}

setParallelCanAssign(function(pickleInQuestion, picklesInProgress) {
return myCustomRule(pickleInQuestion, picklesInProgress) &&
myTagRule(pickleInQuestion, picklesInProgress);
setParallelCanAssign(function (pickleInQuestion, picklesInProgress) {
return (
myCustomRule(pickleInQuestion, picklesInProgress) &&
myTagRule(pickleInQuestion, picklesInProgress)
)
})
```

### Formatting

You can access `workerId` property in `testCaseStarted` envelope object:

```javascript
const { Formatter } = require('@cucumber/cucumber')

class ExampleFormatter extends Formatter {
constructor(options) {
options.eventBroadcaster.on('envelope', (envelope) => {
if (envelope.testCaseStarted) {
if (envelope.testCaseStarted.workerId) {
console.log(
`the event has been fired from a worker with id ${envelope.testCaseStarted.workerId}`
)
} else {
console.log('the event has been sent from the main thread')
}
}
})

super(options)
}
}

module.exports = ExampleFormatter
```
22 changes: 22 additions & 0 deletions features/parallel.feature
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,25 @@ Feature: Running scenarios in parallel
my error
"""
Then it fails

Scenario: `testCaseStarted` envelope from workers contains `workerId` parameter
Given a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')
Given(/^a slow step$/, function(callback) {
setTimeout(callback, 1000)
})
"""
And a file named "features/a.feature" with:
"""
Feature: slow
Scenario: a
Given a slow step
Scenario: b
Given a slow step
"""
When I run cucumber-js with `--parallel 2`
Then it passes
And `testCaseStarted` envelope has `workerId`
8 changes: 8 additions & 0 deletions features/step_definitions/parallel_steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,11 @@ Then(
expect(actualSets).to.eql(expectedSets)
}
)

Then('`testCaseStarted` envelope has `workerId`', function (this: World) {
const testCaseStartedEnvelope = this.lastRun.envelopes.find(
(envelope) => envelope.testCaseStarted
)

expect(testCaseStartedEnvelope.testCaseStarted).to.ownProperty('workerId')
})
Loading

0 comments on commit 3bd70c8

Please sign in to comment.