/
decorators.ts
89 lines (77 loc) · 2.19 KB
/
decorators.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// feature instance
let instance = null;
// all decorated steps
const steps = [];
// loaded expressions
const expressions = [];
export interface FeatureOptions {
stopOnFailure: boolean;
}
// decorate a feature class
export const decorateFeature = (
name: string,
options: FeatureOptions = {
stopOnFailure: true,
}
) => {
return function (target: any) {
target.feature = name;
// load assertions for current feature
before(function () {
const [currentFeature] = Cypress.currentTest.titlePath;
if (!instance && currentFeature === target.feature) {
// load steps for feature and parent features
steps.forEach(([feature, expression, step]) => {
if (
target === feature.constructor ||
target.prototype instanceof feature.constructor
) {
// prevent expression duplication
if (expressions.indexOf(expression) === -1) {
expressions.push(expression);
step();
}
}
});
}
});
// create a fresh instance before each scenario
beforeEach(function () {
const [currentFeature] = Cypress.currentTest.titlePath;
if (!instance && currentFeature === target.feature) {
instance = new target();
}
});
// clear the instance after each scenario
afterEach(function () {
instance = null;
if (options.stopOnFailure && this.currentTest.state === "failed") {
// @ts-expect-error
Cypress.runner.stop();
}
});
};
};
type Implementation = (...args: any[]) => void;
// create a step decorator for a cucumber assertion
export const decorateStep =
(step) =>
(
expression: RegExp | string | Implementation,
implementation?: Implementation
) => {
if (typeof expression === "function" || implementation) {
implementation ? step(expression, implementation) : step(expression);
} else {
return function (target: any, propertyKey: string) {
steps.unshift([
target,
expression,
() =>
step(expression, (...args) => {
instance[propertyKey](...args);
}),
]);
};
}
};