Skip to content

Commit 1d1bc78

Browse files
authored
[patch] nested suites - add Before and After hooks to child suites (#7) (#116)
1 parent 862da62 commit 1d1bc78

File tree

4 files changed

+286
-21
lines changed

4 files changed

+286
-21
lines changed

src/plugins/allure-reporter-plugin.ts

+42-11
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ export class AllureReporter {
149149
globalHooks = new GlobalHooks(this);
150150

151151
// this is variable for global hooks only
152-
hooks: { id?: string; hook: ExecutableItemWrapper }[] = [];
153-
allHooks: { id?: string; hook: ExecutableItemWrapper; suite: string }[] = [];
152+
hooks: { id?: string; hook: ExecutableItemWrapper; nested: number; name: string }[] = [];
153+
allHooks: { id?: string; hook: ExecutableItemWrapper; suite: string; nested: number; name: string }[] = [];
154154
currentSpec: Cypress.Spec | undefined;
155155
allureRuntime: AllureRuntime;
156156
descriptionHtml: string[] = [];
@@ -216,10 +216,10 @@ export class AllureReporter {
216216
return this.currentStep || this.currentHook || this.currentTest;
217217
}
218218

219-
addGlobalHooks() {
219+
addGlobalHooks(nestedLevel: number) {
220220
log('>>> add Global Hooks');
221221

222-
if (this.groups.length > 1 || !this.globalHooks.hasHooks()) {
222+
if (nestedLevel > 1 || !this.globalHooks.hasHooks()) {
223223
log('not root hooks');
224224

225225
return;
@@ -237,8 +237,27 @@ export class AllureReporter {
237237
this.groups.push(group);
238238
log(`SUITES: ${JSON.stringify(this.groups.map(t => t.name))}`);
239239

240-
if (this.groups.length === 1) {
241-
this.addGlobalHooks();
240+
this.addGlobalHooks(this.groups.length);
241+
this.addHooks(this.groups.length);
242+
}
243+
244+
addHooks(nested: number) {
245+
const hooks = this.allHooks.filter(t => t.nested <= nested - 1);
246+
247+
if (!!this.currentGroup && hooks.length > 0) {
248+
hooks.forEach(hk => {
249+
const currentHook = isBeforeAllHook(hk.hook.name)
250+
? this.currentGroup!.addBefore()
251+
: this.currentGroup!.addAfter();
252+
253+
currentHook.name = hk.name;
254+
currentHook.wrappedItem.status = hk.hook.status;
255+
currentHook.wrappedItem.stop = hk.hook.wrappedItem.stop;
256+
currentHook.wrappedItem.start = hk.hook.wrappedItem.start;
257+
currentHook.wrappedItem.attachments = hk.hook.wrappedItem.attachments;
258+
currentHook.wrappedItem.statusDetails = hk.hook.wrappedItem.statusDetails;
259+
currentHook.wrappedItem.parameters = hk.hook.wrappedItem.parameters;
260+
});
242261
}
243262
}
244263

@@ -282,8 +301,14 @@ export class AllureReporter {
282301

283302
currentHook.name = title;
284303
currentHook.wrappedItem.start = date ?? Date.now();
285-
this.hooks.push({ id: hookId, hook: currentHook });
286-
this.allHooks.push({ id: hookId, hook: currentHook, suite: this.currentGroup?.uuid });
304+
this.hooks.push({ id: hookId, hook: currentHook, nested: this.groups.length, name: title });
305+
this.allHooks.push({
306+
id: hookId,
307+
hook: currentHook,
308+
suite: this.currentGroup?.uuid,
309+
nested: this.groups.length,
310+
name: title,
311+
});
287312
} else {
288313
// create but not add to suite for steps to be added there
289314
const currentHook = new ExecutableItemWrapper({
@@ -300,8 +325,14 @@ export class AllureReporter {
300325
});
301326

302327
currentHook.wrappedItem.start = date ?? Date.now();
303-
this.hooks.push({ id: hookId, hook: currentHook });
304-
this.allHooks.push({ id: hookId, hook: currentHook, suite: this.currentGroup?.uuid });
328+
this.hooks.push({ id: hookId, hook: currentHook, nested: this.groups.length, name: title });
329+
this.allHooks.push({
330+
id: hookId,
331+
hook: currentHook,
332+
suite: this.currentGroup?.uuid,
333+
nested: this.groups.length,
334+
name: title,
335+
});
305336
}
306337
}
307338

@@ -582,7 +613,7 @@ export class AllureReporter {
582613
// why >= 1?
583614
if (this.groups.length >= 1) {
584615
log('addGlobalHooks');
585-
this.addGlobalHooks();
616+
this.addGlobalHooks(this.groups.length);
586617
}
587618

588619
if (this.currentGroup) {

tests/cy-helper/utils.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const fixResult = (results: AllureTest[]): AllureTest[] => {
3030
const date = Date.parse('10 Dec 2011 UTC');
3131

3232
const replaceSteps = (steps: ExecutableItem[]): any[] => {
33-
if (steps.length === 0) {
33+
if (!steps || steps.length === 0) {
3434
return [];
3535
}
3636

@@ -328,11 +328,11 @@ export const createResTest2 = (
328328
let err: Error | undefined;
329329
const spec = specPaths.length === 1 ? specPaths[0] : specPaths;
330330

331-
try {
332-
process.env.DEBUG = envConfig?.DEBUG ? 'cypress-allure*' : undefined;
333-
process.env.COVERAGE_REPORT_DIR = 'reports/coverage-cypress';
331+
process.env.DEBUG = envConfig?.DEBUG ? 'cypress-allure*' : undefined;
332+
process.env.COVERAGE_REPORT_DIR = 'reports/coverage-cypress';
334333

335-
result.res = await cy.run({
334+
return cy
335+
.run({
336336
spec,
337337
specPattern: 'integration/e2e/**/*.(cy|test|spec).ts',
338338
port,
@@ -341,12 +341,16 @@ export const createResTest2 = (
341341
env,
342342
quiet: `${process.env.QUIET}` === 'true',
343343
video: parseBoolean(envConfig?.video ?? `${true}`),
344+
})
345+
.catch(e => {
346+
err = e as Error;
347+
})
348+
.then(cyResult => {
349+
result.res = cyResult;
350+
})
351+
.then(() => {
352+
expect(err).toBeUndefined();
344353
});
345-
} catch (e) {
346-
err = e as Error;
347-
}
348-
349-
expect(err).toBeUndefined();
350354
});
351355

352356
return {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import { createResTest2, fixResult } from '../../../cy-helper/utils';
2+
import { getParentsArray, parseAllure } from 'allure-js-parser';
3+
import { extname } from '../../../../src/common';
4+
import { readFileSync } from 'fs';
5+
6+
describe('several nested suites with global hook - hook should be added to all children', () => {
7+
const res = createResTest2([
8+
`
9+
describe('hello suite', () => {
10+
before('parent hook', () => {
11+
cy.allure().attachment('out parent', 'test number', 'text/plain');
12+
cy.log('before');
13+
});
14+
15+
describe('child suite', () => {
16+
before('child hook', () => {
17+
cy.allure().attachment('out child', 'test number', 'text/plain');
18+
cy.log('before');
19+
});
20+
21+
describe('sub sub suite', () => {
22+
it('hello test', () => {
23+
cy.log('message');
24+
});
25+
});
26+
});
27+
});
28+
`,
29+
]);
30+
31+
describe('check results', () => {
32+
let resFixed;
33+
34+
beforeAll(() => {
35+
const results = parseAllure(res.watch);
36+
resFixed = fixResult(results);
37+
});
38+
39+
it('check tests count', async () => {
40+
expect(resFixed.length).toEqual(1);
41+
});
42+
43+
it('check tests names', async () => {
44+
expect(resFixed.map(t => t.fullName).sort()).toEqual([
45+
'hello suite child suite sub sub suite hello test',
46+
]);
47+
});
48+
49+
it('suites parents', () => {
50+
expect(
51+
resFixed.map(t => ({
52+
name: t.name,
53+
status: t.status,
54+
parents: getParentsArray(t).map(t => ({
55+
name: t.name,
56+
befores: t.befores
57+
?.filter(x => (x as any).name !== '"before all" hook')
58+
.map(x => ({
59+
name: (x as any).name,
60+
status: x.status,
61+
attachments: x.attachments.map(t => ({
62+
...t,
63+
source: `source${extname(t.source)}`,
64+
sourceContentMoreThanZero:
65+
readFileSync(`${res.watch}/${t.source}`).toString().length >
66+
0,
67+
})),
68+
})),
69+
})),
70+
})),
71+
).toEqual([
72+
{
73+
name: 'hello test',
74+
parents: [
75+
{
76+
befores: [
77+
{
78+
attachments: [
79+
{
80+
name: 'out parent',
81+
source: 'source.txt',
82+
sourceContentMoreThanZero: true,
83+
type: 'text/plain',
84+
},
85+
],
86+
name: '"before all" hook: parent hook',
87+
status: 'passed',
88+
},
89+
{
90+
attachments: [
91+
{
92+
name: 'out child',
93+
source: 'source.txt',
94+
sourceContentMoreThanZero: true,
95+
type: 'text/plain',
96+
},
97+
],
98+
name: '"before all" hook: child hook',
99+
status: 'passed',
100+
},
101+
],
102+
name: 'sub sub suite',
103+
},
104+
{
105+
befores: [
106+
{
107+
attachments: [
108+
{
109+
name: 'out parent',
110+
source: 'source.txt',
111+
sourceContentMoreThanZero: true,
112+
type: 'text/plain',
113+
},
114+
],
115+
name: '"before all" hook: parent hook',
116+
status: 'passed',
117+
},
118+
{
119+
attachments: [
120+
{
121+
name: 'out child',
122+
source: 'source.txt',
123+
sourceContentMoreThanZero: true,
124+
type: 'text/plain',
125+
},
126+
],
127+
name: '"before all" hook: child hook',
128+
status: 'passed',
129+
},
130+
],
131+
name: 'child suite',
132+
},
133+
{
134+
befores: [
135+
{
136+
attachments: [
137+
{
138+
name: 'out parent',
139+
source: 'source.txt',
140+
sourceContentMoreThanZero: true,
141+
type: 'text/plain',
142+
},
143+
],
144+
name: '"before all" hook: parent hook',
145+
status: 'passed',
146+
},
147+
],
148+
name: 'hello suite',
149+
},
150+
],
151+
status: 'passed',
152+
},
153+
]);
154+
});
155+
});
156+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { createResTest2, fixResult } from '../../../cy-helper/utils';
2+
import { getParentsArray, parseAllure } from 'allure-js-parser';
3+
4+
describe('several nested suites with global hook - hook should be added to all parents', () => {
5+
const res = createResTest2([
6+
`
7+
describe('hello suite', () => {
8+
describe('child suite', () => {
9+
before('Child hook', () => {
10+
cy.log('before');
11+
});
12+
13+
it('hello test', () => {
14+
cy.log('message');
15+
});
16+
});
17+
});
18+
`,
19+
]);
20+
21+
describe('check results', () => {
22+
let resFixed;
23+
24+
beforeAll(() => {
25+
const results = parseAllure(res.watch);
26+
resFixed = fixResult(results);
27+
});
28+
29+
it('check tests count', async () => {
30+
expect(resFixed.length).toEqual(1);
31+
});
32+
33+
it('check tests names', async () => {
34+
expect(resFixed.map(t => t.fullName).sort()).toEqual([
35+
'hello suite child suite hello test',
36+
]);
37+
});
38+
39+
it('suites parents', () => {
40+
expect(
41+
resFixed.map(t => ({
42+
name: t.name,
43+
status: t.status,
44+
parents: getParentsArray(t).map(z => ({
45+
name: z.name,
46+
befores: z.befores
47+
?.filter(x => (x as any).name !== '"before all" hook')
48+
?.map(x => ({ status: x.status, name: (x as any).name })),
49+
})),
50+
})),
51+
).toEqual([
52+
{
53+
name: 'hello test',
54+
parents: [
55+
{
56+
befores: [
57+
{
58+
name: '"before all" hook: Child hook',
59+
status: 'passed',
60+
},
61+
],
62+
name: 'child suite',
63+
},
64+
{
65+
befores: [],
66+
name: 'hello suite',
67+
},
68+
],
69+
status: 'passed',
70+
},
71+
]);
72+
});
73+
});
74+
});

0 commit comments

Comments
 (0)