Skip to content

Commit c5f4c8a

Browse files
committed
Merge branch 'VidhiRambhia/master'
2 parents 17ee4f3 + 186e2b6 commit c5f4c8a

File tree

8 files changed

+120
-18
lines changed

8 files changed

+120
-18
lines changed

features/hooks_ordering.feature

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Feature: hooks ordering
22

33
Hooks should be executed in the following order:
44
- before
5+
- BeforeAll
56
- beforeEach
67
- Before
78
- Background steps
@@ -10,14 +11,17 @@ Feature: hooks ordering
1011
- AfterStep (in reverse order)
1112
- After
1213
- afterEach
14+
- AfterAll
1315
- after
1416

17+
@foo
1518
Scenario: with all hooks incrementing a counter
1619
Given a file named "cypress/e2e/a.feature" with:
1720
"""
1821
Feature: a feature
1922
Background:
2023
Given a background step
24+
@foo
2125
Scenario: a scenario
2226
Given an ordinary step
2327
"""
@@ -28,50 +32,58 @@ Feature: hooks ordering
2832
Before,
2933
After,
3034
BeforeStep,
31-
AfterStep
35+
AfterStep,
36+
BeforeAll,
37+
AfterAll
3238
} = require("@badeball/cypress-cucumber-preprocessor")
3339
let counter;
3440
before(function() {
3541
counter = 0;
3642
})
43+
BeforeAll(() => {
44+
expect(counter++, "Expect BeforeAll() to be called after beforeEach()").to.equal(0)
45+
})
3746
beforeEach(function() {
38-
expect(counter++, "Expected beforeEach() to be called after before()").to.equal(0)
47+
expect(counter++, "Expected beforeEach() to be called after before()").to.equal(1)
3948
})
4049
Before(function() {
41-
expect(counter++, "Expected Before() to be called after beforeEach()").to.equal(1)
50+
expect(counter++, "Expected Before() to be called after beforeEach()").to.equal(2)
4251
})
4352
Given("a background step", function() {
44-
expect(counter++, "Expected a background step to be called after Before()").to.equal(2)
53+
expect(counter++, "Expected a background step to be called after Before()").to.equal(3)
4554
})
4655
BeforeStep(function ({ pickleStep }) {
4756
if (pickleStep.text === "an ordinary step") {
48-
expect(counter++, "Expected BeforeStep() to be called before ordinary steps").to.equal(3)
57+
expect(counter++, "Expected BeforeStep() to be called before ordinary steps").to.equal(4)
4958
}
5059
})
5160
Given("an ordinary step", function() {
52-
expect(counter++, "Expected an ordinary step to be called after a background step").to.equal(4)
61+
expect(counter++, "Expected an ordinary step to be called after a background step").to.equal(5)
5362
})
5463
AfterStep(function ({ pickleStep }) {
5564
if (pickleStep.text === "an ordinary step") {
56-
expect(counter++, "Expected AfterStep() to be called after ordinary steps").to.equal(6)
65+
expect(counter++, "Expected AfterStep() to be called after ordinary steps").to.equal(7)
5766
}
5867
})
5968
AfterStep(function ({ pickleStep }) {
6069
if (pickleStep.text === "an ordinary step") {
61-
expect(counter++, "Expected AfterStep() to be called after ordinary steps").to.equal(5)
70+
expect(counter++, "Expected AfterStep() to be called after ordinary steps").to.equal(6)
6271
}
6372
})
6473
After(function() {
65-
expect(counter++, "Expected After() to be called in reverse order of definition").to.equal(8)
74+
expect(counter++, "Expected After() to be called in reverse order of definition").to.equal(9)
6675
})
6776
After(function() {
68-
expect(counter++, "Expected After() to be called after ordinary steps").to.equal(7)
77+
expect(counter++, "Expected After() to be called after ordinary steps").to.equal(8)
6978
})
7079
afterEach(function() {
71-
expect(counter++, "Expected afterEach() to be called after After()").to.equal(9)
80+
expect(counter++, "Expected afterEach() to be called after After()").to.equal(10)
81+
})
82+
AfterAll(function() {
83+
expect(counter++, "Expected AfterAll() to be called after afterEach()").to.equal(11)
7284
})
7385
after(function() {
74-
expect(counter++, "Expected after() to be called after afterEach()").to.equal(10)
86+
expect(counter++, "Expected after() to be called after AfterAll()").to.equal(12)
7587
})
7688
"""
7789
When I run cypress

lib/browser-runtime.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@ function createFeature(context: CompositionContext, feature: messages.Feature) {
309309
beforeEachHandler.call(this, context);
310310
});
311311

312+
after(function () {
313+
afterAllHandler.call(this, context);
314+
});
315+
312316
afterEach(function () {
313317
afterEachHandler.call(this, context);
314318
});
@@ -765,13 +769,22 @@ function shouldSkipPickle(testFilter: Node, pickle: messages.Pickle) {
765769
return !testFilter.evaluate(tags) || tags.includes("@skip");
766770
}
767771

768-
function beforeHandler(context: CompositionContext) {
772+
function beforeHandler(this: Mocha.Context, context: CompositionContext) {
769773
if (!retrieveInternalSuiteProperties()?.isEventHandlersAttached) {
770774
fail(
771775
"Missing preprocessor event handlers (this usally means you've not invoked `addCucumberPreprocessorPlugin()` or not returned the config object in `setupNodeEvents()`)"
772776
);
773777
}
774-
778+
// Handle BeforeAll hook
779+
const { registry } = context;
780+
const beforeAllHooks = registry.resolveBeforeAllHooks();
781+
for (const beforeAllHook of beforeAllHooks) {
782+
const hook = beforeAllHook;
783+
runStepWithLogGroup({
784+
fn: () => registry.runHook(this, hook),
785+
keyword: "BeforeAll",
786+
});
787+
}
775788
taskSpecEnvelopes(context);
776789
}
777790

@@ -1026,6 +1039,17 @@ function afterEachHandler(this: Mocha.Context, context: CompositionContext) {
10261039
});
10271040
}
10281041

1042+
function afterAllHandler(this: Mocha.Context, context: CompositionContext) {
1043+
const { registry } = context;
1044+
const afterAllHooks = registry.resolveAfterAllHooks();
1045+
for (const afterAllHook of afterAllHooks) {
1046+
const hook = afterAllHook;
1047+
runStepWithLogGroup({
1048+
fn: () => registry.runHook(this, hook),
1049+
keyword: "AfterAll",
1050+
});
1051+
}
1052+
}
10291053
export default function createTests(
10301054
registry: Registry,
10311055
seed: number,
@@ -1079,7 +1103,6 @@ export default function createTests(
10791103
const tags = collectTagNames(pickle.tags);
10801104
const beforeHooks = registry.resolveBeforeHooks(tags);
10811105
const afterHooks = registry.resolveAfterHooks(tags);
1082-
10831106
const hooksToStep = (hook: IHook): messages.TestStep => {
10841107
return {
10851108
id: createTestStepId({

lib/entrypoint-browser.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ function defineAfterStep(
127127
}
128128
}
129129

130+
function defineBeforeAll(fn: IHookBody) {
131+
if (typeof fn === "function") {
132+
getRegistry().defineBeforeAll(fn);
133+
} else {
134+
throw new Error("Unexpected argument for BeforeAll hook");
135+
}
136+
}
137+
138+
function defineAfterAll(fn: IHookBody) {
139+
if (typeof fn === "function") {
140+
getRegistry().defineAfterAll(fn);
141+
} else {
142+
throw new Error("Unexpected argument for AfterAll hook");
143+
}
144+
}
145+
130146
function createStringAttachment(
131147
data: string,
132148
mediaType: string,
@@ -208,6 +224,8 @@ export {
208224
defineAfter as After,
209225
defineBeforeStep as BeforeStep,
210226
defineAfterStep as AfterStep,
227+
defineBeforeAll as BeforeAll,
228+
defineAfterAll as AfterAll,
211229
};
212230

213231
/**

lib/entrypoint-node.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,18 @@ export function AfterStep(
119119
throw createUnimplemented();
120120
}
121121

122+
export function BeforeAll(
123+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
124+
fn: IStepHookBody
125+
) {
126+
throw createUnimplemented();
127+
}
128+
129+
export function AfterAll(
130+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
131+
fn: IHookBody
132+
) {
133+
throw createUnimplemented();
134+
}
135+
122136
export { default as DataTable } from "./data_table";

lib/public-member-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface IHookOptions {
1212
}
1313

1414
export interface IHookBody {
15-
(this: Mocha.Context, options: IHookParameter): void;
15+
(this: Mocha.Context, options?: IHookParameter): void;
1616
}
1717

1818
export interface IHookParameter {

lib/registry.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export class MissingDefinitionError extends CypressCucumberError {}
4242

4343
export class MultipleDefinitionsError extends CypressCucumberError {}
4444

45-
export type ScenarioHookKeyword = "Before" | "After";
45+
export type ScenarioHookKeyword = "Before" | "After" | "BeforeAll" | "AfterAll";
4646

4747
export type StepHookKeyword = "BeforeStep" | "AfterStep";
4848

@@ -208,6 +208,14 @@ export class Registry {
208208
this.defineStepHook("AfterStep", options, fn);
209209
}
210210

211+
public defineBeforeAll(fn: IHookBody) {
212+
this.defineHook("BeforeAll", {}, fn);
213+
}
214+
215+
public defineAfterAll(fn: IHookBody) {
216+
this.defineHook("AfterAll", {}, fn);
217+
}
218+
211219
public getMatchingStepDefinitions(text: string) {
212220
return this.stepDefinitions.filter((stepDefinition) =>
213221
stepDefinition.expression.match(text)
@@ -279,7 +287,7 @@ export class Registry {
279287
return this.resolveHooks("After", tags).reverse();
280288
}
281289

282-
public runHook(world: Mocha.Context, hook: IHook, options: IHookParameter) {
290+
public runHook(world: Mocha.Context, hook: IHook, options?: IHookParameter) {
283291
return hook.implementation.call(world, options);
284292
}
285293

@@ -297,6 +305,13 @@ export class Registry {
297305
return this.resolveStepHooks("AfterStep", tags).reverse();
298306
}
299307

308+
public resolveBeforeAllHooks() {
309+
return this.resolveHooks("BeforeAll", []);
310+
}
311+
312+
public resolveAfterAllHooks() {
313+
return this.resolveHooks("AfterAll", []);
314+
}
300315
public runStepHook(
301316
world: Mocha.Context,
302317
hook: IStepHook,

test-d/entrypoint-browser.test-d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import {
2525
After,
2626
BeforeStep,
2727
AfterStep,
28+
BeforeAll,
29+
AfterAll,
2830
DataTable,
2931
} from "../lib/entrypoint-browser";
3032

@@ -138,6 +140,10 @@ defineParameterType({
138140
},
139141
});
140142

143+
BeforeAll(function () {
144+
expectType<Mocha.Context>(this);
145+
});
146+
141147
Before(function () {
142148
expectType<Mocha.Context>(this);
143149
});
@@ -162,6 +168,10 @@ After({ tags: "foo", name: "bar" }, function () {
162168
expectType<Mocha.Context>(this);
163169
});
164170

171+
AfterAll(function () {
172+
expectType<Mocha.Context>(this);
173+
});
174+
165175
BeforeStep(function ({
166176
pickle,
167177
pickleStep,

test-d/entrypoint-node.test-d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import {
2525
After,
2626
BeforeStep,
2727
AfterStep,
28+
BeforeAll,
29+
AfterAll,
2830
DataTable,
2931
} from "../lib/entrypoint-node";
3032

@@ -138,6 +140,10 @@ defineParameterType({
138140
},
139141
});
140142

143+
BeforeAll(function () {
144+
expectType<Mocha.Context>(this);
145+
});
146+
141147
Before(function () {
142148
expectType<Mocha.Context>(this);
143149
});
@@ -162,6 +168,10 @@ After({ tags: "foo", name: "bar" }, function () {
162168
expectType<Mocha.Context>(this);
163169
});
164170

171+
AfterAll(function () {
172+
expectType<Mocha.Context>(this);
173+
});
174+
165175
BeforeStep(function ({
166176
pickle,
167177
pickleStep,

0 commit comments

Comments
 (0)