From d5fa4ba1765d3d97c1590a3365ab2bd668a6bfc7 Mon Sep 17 00:00:00 2001 From: David Goss Date: Sat, 21 Aug 2021 11:20:48 +0100 Subject: [PATCH 1/5] add to interface --- src/support_code_library_builder/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/support_code_library_builder/types.ts b/src/support_code_library_builder/types.ts index 693dd8a2b..4738353e6 100644 --- a/src/support_code_library_builder/types.ts +++ b/src/support_code_library_builder/types.ts @@ -18,6 +18,7 @@ export interface ITestCaseHookParameter { export interface ITestStepHookParameter { gherkinDocument: messages.GherkinDocument pickle: messages.Pickle + pickleStep: messages.PickleStep result: messages.TestStepResult testCaseStartedId: string testStepId: string From ae4b1472afde3f95705f2728ced758d922ea94b5 Mon Sep 17 00:00:00 2001 From: David Goss Date: Sat, 21 Aug 2021 11:25:06 +0100 Subject: [PATCH 2/5] implement --- src/runtime/test_case_runner.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/runtime/test_case_runner.ts b/src/runtime/test_case_runner.ts index e5a910a24..c9dfe5b69 100644 --- a/src/runtime/test_case_runner.ts +++ b/src/runtime/test_case_runner.ts @@ -257,12 +257,14 @@ export default class TestCaseRunner { async runStepHooks( stepHooks: TestStepHookDefinition[], + pickleStep: messages.PickleStep, stepResult?: messages.TestStepResult ): Promise { const stepHooksResult = [] const hookParameter: ITestStepHookParameter = { gherkinDocument: this.gherkinDocument, pickle: this.pickle, + pickleStep, testCaseStartedId: this.currentTestCaseStartedId, testStepId: this.currentTestStepId, result: stepResult, @@ -307,7 +309,8 @@ export default class TestCaseRunner { let stepResult let stepResults = await this.runStepHooks( - this.getBeforeStepHookDefinitions() + this.getBeforeStepHookDefinitions(), + pickleStep ) if ( getWorstTestStepResult(stepResults).status !== @@ -318,6 +321,7 @@ export default class TestCaseRunner { } const afterStepHookResults = await this.runStepHooks( this.getAfterStepHookDefinitions(), + pickleStep, stepResult ) stepResults = stepResults.concat(afterStepHookResults) From c8a2e5c88ce38dbca41ef6687f5da77266a1ce5a Mon Sep 17 00:00:00 2001 From: David Goss Date: Sat, 21 Aug 2021 11:26:31 +0100 Subject: [PATCH 3/5] update api ref --- docs/support_files/api_reference.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/support_files/api_reference.md b/docs/support_files/api_reference.md index e47a01570..0e9ee94cd 100644 --- a/docs/support_files/api_reference.md +++ b/docs/support_files/api_reference.md @@ -69,8 +69,9 @@ Defines a hook which is run after each step. * `tags`: String tag expression used to apply this hook to only specific scenarios. See [cucumber-tag-expressions](https://docs.cucumber.io/tag-expressions/) for more information. * `timeout`: A hook-specific timeout, to override the default timeout. * `fn`: A function, defined as follows: - * The first argument will be an object of the form `{pickle, gherkinDocument, result, testCaseStartedId, testStepId}` - * The pickle object comes from the [gherkin](https://github.com/cucumber/cucumber/tree/gherkin/v15.0.2/gherkin) library. See `testdata/good/*.pickles.ndjson` for examples of its structure. + * The first argument will be an object of the form `{pickle, pickleStep, gherkinDocument, result, testCaseStartedId, testStepId}` + * The `pickle` object comes from the [gherkin](https://github.com/cucumber/cucumber/tree/gherkin/v15.0.2/gherkin) library. See `testdata/good/*.pickles.ndjson` for examples of its structure. + * The `pickleStep` is the step in the `pickle` that this hook has been invoked for * When using the asynchronous callback interface, have one final argument for the callback function. `options` can also be a string as a shorthand for specifying `tags`. From 75f6ab978087c249c4b2da9ae61e6e3e894d592b Mon Sep 17 00:00:00 2001 From: David Goss Date: Sat, 21 Aug 2021 11:28:06 +0100 Subject: [PATCH 4/5] update changelgo --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32d9c3602..0c3dda7b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ See the [migration guide](./docs/migration.md) for details of how to migrate fro ### Added +* `BeforeStep` and `AfterStep` hook functions now have access to the `pickleStep` in their argument object. + ### Changed ### Deprecated From 3aa281180244b193281ca50929bb370f789fd2c4 Mon Sep 17 00:00:00 2001 From: David Goss Date: Sat, 21 Aug 2021 11:58:10 +0100 Subject: [PATCH 5/5] add test --- src/runtime/test_case_runner_spec.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/runtime/test_case_runner_spec.ts b/src/runtime/test_case_runner_spec.ts index 9e69b25f8..dc9070fd0 100644 --- a/src/runtime/test_case_runner_spec.ts +++ b/src/runtime/test_case_runner_spec.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, it } from 'mocha' import { expect } from 'chai' +import sinon from 'sinon' import TestCaseRunner from './test_case_runner' import { EventEmitter } from 'events' import { IdGenerator } from '@cucumber/messages' @@ -438,14 +439,17 @@ describe('TestCaseRunner', () => { describe('with step hooks', () => { it('emits the expected envelopes and returns a skipped result', async () => { + const beforeStep = sinon.stub() + const afterStep = sinon.stub() + // Arrange const supportCodeLibrary = buildSupportCodeLibrary( ({ Given, BeforeStep, AfterStep }) => { Given('a step', function () { clock.tick(1) }) - BeforeStep(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function - AfterStep(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function + BeforeStep(beforeStep) // eslint-disable-line @typescript-eslint/no-empty-function + AfterStep(afterStep) // eslint-disable-line @typescript-eslint/no-empty-function } ) const { @@ -468,6 +472,22 @@ describe('TestCaseRunner', () => { expect(result).to.eql( envelopes[2].testStepFinished.testStepResult.status ) + expect(beforeStep).to.have.been.calledOnceWith({ + gherkinDocument, + pickle, + pickleStep: pickle.steps[0], + testCaseStartedId: envelopes[1].testStepStarted.testCaseStartedId, + testStepId: envelopes[1].testStepStarted.testStepId, + result: undefined, + }) + expect(afterStep).to.have.been.calledOnceWith({ + gherkinDocument, + pickle, + pickleStep: pickle.steps[0], + testCaseStartedId: envelopes[2].testStepFinished.testCaseStartedId, + testStepId: envelopes[2].testStepFinished.testStepId, + result: envelopes[2].testStepFinished.testStepResult, + }) }) }) })