Skip to content

Commit 47331fb

Browse files
authored
fixed metadata steps in playwright hooks (#1455)
1 parent 92758b7 commit 47331fb

2 files changed

Lines changed: 387 additions & 55 deletions

File tree

packages/allure-playwright/src/index.ts

Lines changed: 93 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ export class AllureReporter implements ReporterV2 {
7676
private readonly attachmentTargets: Map<string, AttachmentTarget[]> = new Map();
7777
private beforeHooksStepsStack: Map<string, ShallowStepsStack> = new Map();
7878
private afterHooksStepsStack: Map<string, ShallowStepsStack> = new Map();
79-
private beforeHooksAttachmentsStack: Map<string, AttachStack[]> = new Map();
80-
private afterHooksAttachmentsStack: Map<string, AttachStack[]> = new Map();
8179
private readonly pwStepUuid = new WeakMap<TestStep, string>();
8280
private readonly testPlan = parseTestPlan();
8381

@@ -280,6 +278,24 @@ export class AllureReporter implements ReporterV2 {
280278
return false;
281279
}
282280

281+
#getOrCreateHookStack(testId: string, isBeforeHook: boolean, startTime: Date): ShallowStepsStack {
282+
const map = isBeforeHook ? this.beforeHooksStepsStack : this.afterHooksStepsStack;
283+
let stack = map.get(testId);
284+
if (!stack) {
285+
stack = new ShallowStepsStack();
286+
const rootHookStep: StepResult = {
287+
...createStepResult(),
288+
name: isBeforeHook ? BEFORE_HOOKS_ROOT_STEP_TITLE : AFTER_HOOKS_ROOT_STEP_TITLE,
289+
start: startTime.getTime(),
290+
stage: Stage.RUNNING,
291+
uuid: randomUuid(),
292+
};
293+
stack.startStep(rootHookStep);
294+
map.set(testId, stack);
295+
}
296+
return stack;
297+
}
298+
283299
onStepBegin(test: TestCase, _result: PlaywrightTestResult, step: TestStep): void {
284300
const isRootBeforeHook = step.title === BEFORE_HOOKS_ROOT_STEP_TITLE;
285301
const isRootAfterHook = step.title === AFTER_HOOKS_ROOT_STEP_TITLE;
@@ -310,48 +326,33 @@ export class AllureReporter implements ReporterV2 {
310326
}
311327

312328
if (isHookStep) {
313-
// Lazily initialize the hook stack if it doesn't exist (e.g., when detail: false and root hook was ignored)
314-
let stack = isBeforeHookDescendant
315-
? this.beforeHooksStepsStack.get(test.id)
316-
: this.afterHooksStepsStack.get(test.id);
317-
318-
if (!stack) {
319-
stack = new ShallowStepsStack();
320-
const rootHookStep: StepResult = {
321-
...createStepResult(),
322-
name: isBeforeHookDescendant ? BEFORE_HOOKS_ROOT_STEP_TITLE : AFTER_HOOKS_ROOT_STEP_TITLE,
323-
start: step.startTime.getTime(),
324-
stage: Stage.RUNNING,
325-
uuid: randomUuid(),
326-
};
327-
stack.startStep(rootHookStep);
328-
if (isBeforeHookDescendant) {
329-
this.beforeHooksStepsStack.set(test.id, stack);
330-
} else {
331-
this.afterHooksStepsStack.set(test.id, stack);
332-
}
333-
}
334-
335329
if (["test.attach", "attach"].includes(step.category)) {
330+
const attachmentName = normalizeAttachStepTitle(step.title);
331+
const stack = this.#getOrCreateHookStack(test.id, isBeforeHookDescendant, step.startTime);
332+
336333
let hookStepWithUuid: AttachStack | undefined;
334+
const parentHookStepUuid = stack.currentStep()?.uuid;
337335
stack.startStep(baseStep);
338336

339-
const attachStack = isBeforeHookDescendant ? this.beforeHooksAttachmentsStack : this.afterHooksAttachmentsStack;
340-
341337
stack.updateStep((stepResult) => {
342338
hookStepWithUuid = { ...step, uuid: stepResult.uuid as string } as AttachStack;
343339
stepResult.name = normalizeHookTitle(stepResult.name!);
344340
stepResult.stage = Stage.FINISHED;
345-
attachStack.set(test.id, [...(attachStack.get(test.id) ?? []), hookStepWithUuid]);
346341
});
347342
stack.stopStep();
348343

349344
const targets = this.attachmentTargets.get(test.id) ?? [];
350-
targets.push({ name: normalizeAttachStepTitle(step.title), hookStep: hookStepWithUuid });
345+
targets.push({
346+
name: attachmentName,
347+
hookStep: hookStepWithUuid,
348+
stepUuid: attachmentName === "Allure Step Metadata" ? parentHookStepUuid : undefined,
349+
});
351350
this.attachmentTargets.set(test.id, targets);
352351
return;
353352
}
354353

354+
const stack = this.#getOrCreateHookStack(test.id, isBeforeHookDescendant, step.startTime);
355+
355356
stack.startStep(baseStep);
356357
return;
357358
}
@@ -505,8 +506,6 @@ export class AllureReporter implements ReporterV2 {
505506
);
506507
}
507508

508-
const attachmentsInBeforeHooks = this.beforeHooksAttachmentsStack.get(test.id) ?? [];
509-
510509
// FIFO
511510
const targets = this.attachmentTargets.get(test.id) ?? [];
512511
const targetsByName = new Map<string, AttachmentTarget[]>();
@@ -529,15 +528,31 @@ export class AllureReporter implements ReporterV2 {
529528
const stepInfo = takeByName(attachment.name);
530529

531530
if (isRuntimeMessage) {
531+
const message = attachment.body ? (JSON.parse(attachment.body.toString()) as RuntimeMessage) : undefined;
532+
533+
if (stepInfo?.hookStep) {
534+
const targetStack = isBeforeHookStep(stepInfo.hookStep) ? beforeHooksStack : afterHooksStack;
535+
this.removeStepFromHookStack(targetStack, stepInfo.hookStep.uuid);
536+
}
537+
538+
if (message?.type === "step_metadata" && stepInfo?.stepUuid) {
539+
if (stepInfo.hookStep) {
540+
const targetStack = isBeforeHookStep(stepInfo.hookStep) ? beforeHooksStack : afterHooksStack;
541+
this.processHookStepMetadataMessage(targetStack, stepInfo.stepUuid, message);
542+
} else {
543+
this.processStepMetadataMessage(stepInfo.stepUuid, message);
544+
}
545+
continue;
546+
}
547+
532548
const stepUuid = stepInfo?.hookStep?.uuid ?? stepInfo?.stepUuid;
533549
await this.processAttachment(testUuid, stepUuid, attachment);
534550
continue;
535551
}
536552

537553
if (stepInfo?.hookStep) {
538554
const hookStep = stepInfo.hookStep;
539-
const isBeforeHook = attachmentsInBeforeHooks.includes(hookStep);
540-
const targetStack = isBeforeHook ? beforeHooksStack : afterHooksStack;
555+
const targetStack = isBeforeHookStep(hookStep) ? beforeHooksStack : afterHooksStack;
541556

542557
if (targetStack) {
543558
const stepResult = targetStack.findStepByUuid(hookStep.uuid);
@@ -589,13 +604,13 @@ export class AllureReporter implements ReporterV2 {
589604

590605
if (beforeHooksStack) {
591606
testResult.steps.unshift(...beforeHooksStack.steps);
592-
this.beforeHooksStepsStack.delete(test.id);
593607
}
608+
this.beforeHooksStepsStack.delete(test.id);
594609

595610
if (afterHooksStack) {
596611
testResult.steps.push(...afterHooksStack.steps);
597-
this.afterHooksStepsStack.delete(test.id);
598612
}
613+
this.afterHooksStepsStack.delete(test.id);
599614

600615
testResult.labels = newLabels;
601616
});
@@ -641,6 +656,30 @@ export class AllureReporter implements ReporterV2 {
641656
return false;
642657
}
643658

659+
private removeStepFromHookStack(stack: ShallowStepsStack | undefined, stepUuid: string) {
660+
if (!stack) {
661+
return;
662+
}
663+
664+
const removeRecursively = (steps: StepResult[]): StepResult[] => {
665+
return steps
666+
.filter((step) => step.uuid !== stepUuid)
667+
.map((step) => ({
668+
...step,
669+
steps: removeRecursively(step.steps),
670+
}))
671+
.filter(
672+
(step) =>
673+
(step.name !== BEFORE_HOOKS_ROOT_STEP_TITLE && step.name !== AFTER_HOOKS_ROOT_STEP_TITLE) ||
674+
step.steps.length > 0 ||
675+
step.attachments.length > 0 ||
676+
step.status !== Status.PASSED,
677+
);
678+
};
679+
680+
stack.steps = removeRecursively(stack.steps);
681+
}
682+
644683
private getStaticTestMetadata(test: TestCase) {
645684
const titleMetadata = extractMetadataFromString(test.title);
646685
const project =
@@ -719,6 +758,26 @@ export class AllureReporter implements ReporterV2 {
719758
});
720759
}
721760

761+
private processHookStepMetadataMessage(
762+
stack: ShallowStepsStack | undefined,
763+
attachmentStepUuid: string,
764+
message: RuntimeStepMetadataMessage,
765+
) {
766+
const step = stack?.findStepByUuid(attachmentStepUuid);
767+
768+
if (!step) {
769+
return;
770+
}
771+
772+
const { name, parameters = [] } = message.data;
773+
774+
if (name) {
775+
step.name = name;
776+
}
777+
778+
step.parameters.push(...parameters);
779+
}
780+
722781
private async processAttachment(
723782
testUuid: string,
724783
attachmentStepUuid: string | undefined,
@@ -741,11 +800,6 @@ export class AllureReporter implements ReporterV2 {
741800

742801
if (allureRuntimeMessage) {
743802
const message = JSON.parse(attachment.body!.toString()) as RuntimeMessage;
744-
745-
if (message.type === "step_metadata") {
746-
this.processStepMetadataMessage(attachmentStepUuid!, message);
747-
return;
748-
}
749803
this.allureRuntime!.applyRuntimeMessages(testUuid, [message]);
750804
return;
751805
}

0 commit comments

Comments
 (0)