Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions lib/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,8 @@ async function loadGherkinStepsAsync(paths) {
// Import BDD module to access step file tracking functions and step DSL
const bddModule = await import('./mocha/bdd.js')

global.Before = fn => event.dispatcher.on(event.test.started, fn)
global.After = fn => event.dispatcher.on(event.test.finished, fn)
global.Before = global.GherkinBefore = fn => event.dispatcher.on(event.test.started, fn)
global.After = global.GherkinAfter = fn => event.dispatcher.on(event.test.finished, fn)
global.Fail = fn => event.dispatcher.on(event.test.failed, fn)

// Scope-inject Given/When/Then/And while loading step files so they work
Expand Down Expand Up @@ -818,7 +818,9 @@ async function loadGherkinStepsAsync(paths) {
}

delete global.Before
delete global.GherkinBefore
delete global.After
delete global.GherkinAfter
delete global.Fail
if (injectStepDsl) {
delete global.Given
Expand Down
20 changes: 19 additions & 1 deletion lib/mocha/bdd.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,33 @@ const Before = fn => {
event.dispatcher.on(event.test.started, fn)
}

const GherkinBefore = Before

const After = fn => {
event.dispatcher.on(event.test.finished, fn)
}

const GherkinAfter = After

const Fail = fn => {
event.dispatcher.on(event.test.failed, fn)
}

export { Given, When, Then, And, Before, After, Fail, matchStep, getSteps, clearSteps, defineParameterType }
export {
Given,
When,
Then,
And,
Before,
GherkinBefore,
After,
GherkinAfter,
Fail,
matchStep,
getSteps,
clearSteps,
defineParameterType
}

export default {
Given: addStep,
Expand Down
2 changes: 1 addition & 1 deletion test/data/sandbox/codecept.workers-gherkin.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const config = {
},
gherkin: {
features: './workers-gherkin/*.feature',
steps: ['./workers-gherkin/steps.js'],
steps: ['./workers-gherkin/steps.js', './workers-gherkin/hooks.js'],
},
include: {},
bootstrap: false,
Expand Down
8 changes: 8 additions & 0 deletions test/data/sandbox/workers-gherkin/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
let beforeCounter = 0;
let afterCounter = 0;
GherkinBefore((test) => {
test.addNote('before', `beforeCounter=${++beforeCounter}`);
});
GherkinAfter((test) => {
test.addNote('after', `afterCounter=${++afterCounter}`);
});
9 changes: 9 additions & 0 deletions test/data/sandbox/workers-gherkin/multi.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Feature: Worker gherkin multi scenario

Scenario Outline: runs once @worker_gherkin_multi
Given I open a browser on a site

Examples:
| id |
| 1 |
| 2 |
27 changes: 27 additions & 0 deletions test/unit/worker_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,4 +444,31 @@ describe('Workers', function () {
})
})

it('should run GherkinBefore and GherkinAfter hooks', done => {
const workerConfig = {
by: 'test',
testConfig: './test/data/sandbox/codecept.workers-gherkin.conf.js',
options: {
grep: '@worker_gherkin_multi',
},
}

let passedCount = 0
const workers = new Workers(1, workerConfig)

workers.on(event.test.passed, (test) => {
passedCount += 1
expect(test.notes[0].type).to.equal('before')
expect(test.notes[0].text).to.equal(`beforeCounter=${passedCount}`)
expect(test.notes[1].type).to.equal('after')
expect(test.notes[1].text).to.equal(`afterCounter=${passedCount}`)
})

workers.run()

workers.on(event.all.result, result => {
done()
})
})

})
32 changes: 25 additions & 7 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,12 @@ declare namespace CodeceptJS {
// Could get extended by user generated typings
interface Methods extends ActorStatic {}
interface I {}
interface IHook {}
interface IHook {
(callback: HookCallback): HookConfig
}
interface IHookSuite {
(callback: HookSuiteCallback): HookConfig
}
interface IScenario {}
interface IFeature {
(title: string, opts?: { [key: string]: any }): FeatureConfig
Expand Down Expand Up @@ -508,8 +513,22 @@ declare namespace CodeceptJS {

type StringOrSecret = string | CodeceptJS.Secret

interface GherkinCallback {
(test: Test): void | Promise<void>
}
interface GherkinEventEmitter {}
interface GherkinHook {
(callback: GherkinCallback): GherkinEventEmitter
}
interface HookCallback {
(args: SupportObject): void | Promise<void>
// `suite` has type Mocha.Suite if hook (Background/Before/After) is called before `Feature()`
// `suite` has type CodeceptJS.Suite if hook is called after `Feature()`
(args: SupportObject & { suite: Mocha.Suite; test: Test }): void | Promise<void>
}
interface HookSuiteCallback {
// `suite` has type Mocha.Suite if hook (BeforeSuite/AfterSuite) is called before `Feature()`
// `suite` has type CodeceptJS.Suite if hook is called after `Feature()`
(args: SupportObject & { suite: Mocha.Suite }): void | Promise<void>
}
interface Scenario extends IScenario {
only: IScenario
Expand All @@ -530,9 +549,6 @@ declare namespace CodeceptJS {
(title: string, callback?: HookCallback): ScenarioConfig
(title: string, opts: { [key: string]: any }, callback: HookCallback): ScenarioConfig
}
interface IHook {
(callback: HookCallback): HookConfig
}

interface Globals {
codeceptjs: typeof codeceptjs
Expand Down Expand Up @@ -580,11 +596,13 @@ declare function xData(data: any): CodeceptJS.IData
declare function DefineParameterType(options: CodeceptJS.IParameterTypeDefinition<any>): void

// Hooks
declare const BeforeSuite: CodeceptJS.IHook
declare const AfterSuite: CodeceptJS.IHook
declare const BeforeSuite: CodeceptJS.IHookSuite
declare const AfterSuite: CodeceptJS.IHookSuite
declare const Background: CodeceptJS.IHook
declare const Before: CodeceptJS.IHook
declare const After: CodeceptJS.IHook
declare const GherkinBefore: CodeceptJS.GherkinHook
declare const GherkinAfter: CodeceptJS.GherkinHook

// Plugins
declare const __: any
Expand Down
10 changes: 5 additions & 5 deletions typings/tests/global-variables.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ expectType<CodeceptJS.ScenarioConfig>(
expectType<CodeceptJS.ScenarioConfig>(
Scenario('scenario', args => {
// @ts-ignore
expectType<CodeceptJS.SupportObject>(args)
expectType<CodeceptJS.SupportObject & { suite: Mocha.Suite; test: CodeceptJS.Test }>(args)
// @ts-ignore
expectType<CodeceptJS.I>(args.I) // $ExpectType I
}),
Expand All @@ -72,7 +72,7 @@ expectType<CodeceptJS.ScenarioConfig>(
expectType<CodeceptJS.HookConfig>(
Before(args => {
// @ts-ignore
expectType<CodeceptJS.SupportObject>(args)
expectType<CodeceptJS.SupportObject & { suite: Mocha.Suite; test: CodeceptJS.Test }>(args)
// @ts-ignore
expectType<CodeceptJS.I>(args.I)
}),
Expand All @@ -82,7 +82,7 @@ expectType<CodeceptJS.HookConfig>(
expectType<CodeceptJS.HookConfig>(
BeforeSuite(args => {
// @ts-ignore
expectType<CodeceptJS.SupportObject>(args)
expectType<CodeceptJS.SupportObject & { suite: Mocha.Suite }>(args)
// @ts-ignore
expectType<CodeceptJS.I>(args.I)
}),
Expand All @@ -92,7 +92,7 @@ expectType<CodeceptJS.HookConfig>(
expectType<CodeceptJS.HookConfig>(
After(args => {
// @ts-ignore
expectType<CodeceptJS.SupportObject>(args)
expectType<CodeceptJS.SupportObject & { suite: Mocha.Suite; test: CodeceptJS.Test }>(args)
// @ts-ignore
expectType<CodeceptJS.I>(args.I)
}),
Expand All @@ -102,7 +102,7 @@ expectType<CodeceptJS.HookConfig>(
expectType<CodeceptJS.HookConfig>(
AfterSuite(args => {
// @ts-ignore
expectType<CodeceptJS.SupportObject>(args)
expectType<CodeceptJS.SupportObject & { suite: Mocha.Suite }>(args)
// @ts-ignore
expectType<CodeceptJS.I>(args.I)
}),
Expand Down