@@ -69,7 +69,7 @@ export class AllureReporter implements ReporterV2 {
6969 private processedDiffs : string [ ] = [ ] ;
7070 private readonly startedTestCasesTitlesCache : string [ ] = [ ] ;
7171 private readonly allureResultsUuids : Map < string , string > = new Map ( ) ;
72- private readonly attachmentSteps : Map < string , ( string | undefined ) [ ] > = new Map ( ) ;
72+ private readonly attachmentTargets : Map < string , { stepUuid ?: string ; hookStep ?: AttachStack } [ ] > = new Map ( ) ;
7373 private beforeHooksStepsStack : Map < string , ShallowStepsStack > = new Map ( ) ;
7474 private afterHooksStepsStack : Map < string , ShallowStepsStack > = new Map ( ) ;
7575 private beforeHooksAttachmentsStack : Map < string , AttachStack [ ] > = new Map ( ) ;
@@ -260,7 +260,7 @@ export class AllureReporter implements ReporterV2 {
260260 }
261261
262262 #shouldIgnoreStep( step : TestStep ) {
263- if ( ! this . options . detail && step . category !== "test.step" ) {
263+ if ( ! this . options . detail && ! [ "test.step" , "attach" , "test.attach" ] . includes ( step . category ) ) {
264264 return true ;
265265 }
266266
@@ -286,12 +286,6 @@ export class AllureReporter implements ReporterV2 {
286286 const isHookStep = isBeforeHookDescendant || isAfterHookDescendant ;
287287 const testUuid = this . allureResultsUuids . get ( test . id ) ! ;
288288
289- if ( [ "test.attach" , "attach" ] . includes ( step . category ) && ! isHookStep ) {
290- const currentStep = this . allureRuntime ?. currentStep ( testUuid ) ;
291- this . attachmentSteps . set ( testUuid , [ ...( this . attachmentSteps . get ( testUuid ) ?? [ ] ) , currentStep ] ) ;
292- return ;
293- }
294-
295289 if ( this . #shouldIgnoreStep( step ) ) {
296290 return ;
297291 }
@@ -304,24 +298,38 @@ export class AllureReporter implements ReporterV2 {
304298 uuid : randomUuid ( ) ,
305299 } ;
306300
301+ if ( [ "test.attach" , "attach" ] . includes ( step . category ) && ! isHookStep ) {
302+ const parent = step . parent ? this . pwStepUuid . get ( step . parent ) ?? null : null ;
303+ const targets = this . attachmentTargets . get ( test . id ) ?? [ ] ;
304+ targets . push ( { stepUuid : parent ?? undefined } ) ;
305+ this . attachmentTargets . set ( test . id , targets ) ;
306+ return ;
307+ }
307308 if ( isHookStep ) {
308309 const stack = isBeforeHookDescendant
309310 ? this . beforeHooksStepsStack . get ( test . id ) !
310311 : this . afterHooksStepsStack . get ( test . id ) ! ;
311312
312313 if ( [ "test.attach" , "attach" ] . includes ( step . category ) ) {
314+ let hookStepWithUuid : AttachStack | undefined ;
313315 stack . startStep ( baseStep ) ;
314316
315317 const attachStack = isBeforeHookDescendant ? this . beforeHooksAttachmentsStack : this . afterHooksAttachmentsStack ;
316318
317319 stack . updateStep ( ( stepResult ) => {
320+ hookStepWithUuid = { ...step , uuid : stepResult . uuid as string } as AttachStack ;
318321 stepResult . name = normalizeHookTitle ( stepResult . name ! ) ;
319322 stepResult . stage = Stage . FINISHED ;
320- attachStack . set ( test . id , [ ...( attachStack . get ( test . id ) ?? [ ] ) , { ... step , uuid : stepResult . uuid as string } ] ) ;
323+ attachStack . set ( test . id , [ ...( attachStack . get ( test . id ) ?? [ ] ) , hookStepWithUuid ] ) ;
321324 } ) ;
322325 stack . stopStep ( ) ;
326+
327+ const targets = this . attachmentTargets . get ( test . id ) ?? [ ] ;
328+ targets . push ( { hookStep : hookStepWithUuid } ) ;
329+ this . attachmentTargets . set ( test . id , targets ) ;
323330 return ;
324331 }
332+
325333 stack . startStep ( baseStep ) ;
326334 return ;
327335 }
@@ -336,6 +344,7 @@ export class AllureReporter implements ReporterV2 {
336344 }
337345 return ;
338346 }
347+
339348 const parentUuid = step . parent ? this . pwStepUuid . get ( step . parent ) ?? null : null ;
340349 const createdUuid = this . allureRuntime ! . startStep ( testUuid , parentUuid , baseStep ) ;
341350
@@ -384,6 +393,7 @@ export class AllureReporter implements ReporterV2 {
384393 }
385394
386395 const stepUuid = this . pwStepUuid . get ( step ) ;
396+
387397 if ( ! stepUuid ) {
388398 return ;
389399 }
@@ -442,53 +452,6 @@ export class AllureReporter implements ReporterV2 {
442452 testResult . stage = Stage . FINISHED ;
443453 } ) ;
444454
445- const attachmentsInBeforeHooks = this . beforeHooksAttachmentsStack . get ( test . id ) ?? [ ] ;
446- const attachmentsInAfterHooks = this . afterHooksAttachmentsStack . get ( test . id ) ?? [ ] ;
447- const attachmentSteps = this . attachmentSteps . get ( testUuid ) ?? [ ] ;
448-
449- const attachmentToStepMap = new Map < number , { stepUuid ?: string ; isHook : boolean ; hookStep ?: AttachStack } > ( ) ;
450-
451- let attachmentIndex = 0 ;
452-
453- for ( const hookStep of attachmentsInBeforeHooks ) {
454- attachmentToStepMap . set ( attachmentIndex , {
455- stepUuid : hookStep . uuid ,
456- isHook : true ,
457- hookStep,
458- } ) ;
459- attachmentIndex ++ ;
460- }
461-
462- for ( const stepUuid of attachmentSteps ) {
463- attachmentToStepMap . set ( attachmentIndex , {
464- stepUuid,
465- isHook : false ,
466- } ) ;
467- attachmentIndex ++ ;
468- }
469-
470- for ( const hookStep of attachmentsInAfterHooks ) {
471- attachmentToStepMap . set ( attachmentIndex , {
472- stepUuid : hookStep . uuid ,
473- isHook : true ,
474- hookStep,
475- } ) ;
476- attachmentIndex ++ ;
477- }
478-
479- for ( let i = 0 ; i < result . attachments . length ; i ++ ) {
480- const attachment = result . attachments [ i ] ;
481- const stepInfo = attachmentToStepMap . get ( i ) ;
482-
483- if ( stepInfo ?. isHook ) {
484- continue ;
485- } else if ( stepInfo ?. stepUuid ) {
486- await this . processAttachment ( testUuid , stepInfo . stepUuid , attachment ) ;
487- } else {
488- await this . processAttachment ( testUuid , undefined , attachment ) ;
489- }
490- }
491-
492455 if ( result . stdout . length > 0 ) {
493456 this . allureRuntime ! . writeAttachment (
494457 testUuid ,
@@ -513,23 +476,26 @@ export class AllureReporter implements ReporterV2 {
513476 ) ;
514477 }
515478
516- // FIXME: temp logic for labels override, we need it here to keep the reporter compatible with v2 API
517- // in next iterations we need to implement the logic for every javascript integration
479+ const attachmentsInBeforeHooks = this . beforeHooksAttachmentsStack . get ( test . id ) ?? [ ] ;
480+ const attachmentTargets = this . attachmentTargets . get ( test . id ) ?? [ ] ;
518481
519- for ( let i = 0 ; i < result . attachments . length ; i ++ ) {
520- const attachment = result . attachments [ i ] ;
521- const stepInfo = attachmentToStepMap . get ( i ) ;
482+ let targetIndex = 0 ;
483+
484+ for ( const attachment of result . attachments ) {
485+ const isRuntimeMessage = attachment . contentType === ALLURE_RUNTIME_MESSAGE_CONTENT_TYPE ;
486+ const stepInfo = targetIndex < attachmentTargets . length ? attachmentTargets [ targetIndex ++ ] : undefined ;
487+
488+ if ( isRuntimeMessage ) {
489+ const stepUuid = stepInfo ?. hookStep ?. uuid ?? stepInfo ?. stepUuid ;
490+ await this . processAttachment ( testUuid , stepUuid , attachment ) ;
491+ continue ;
492+ }
522493
523- if ( stepInfo ?. isHook && stepInfo . hookStep ) {
494+ if ( stepInfo ?. hookStep ) {
524495 const hookStep = stepInfo . hookStep ;
525496 const isBeforeHook = attachmentsInBeforeHooks . includes ( hookStep ) ;
526497 const targetStack = isBeforeHook ? beforeHooksStack : afterHooksStack ;
527498
528- if ( attachment . contentType === ALLURE_RUNTIME_MESSAGE_CONTENT_TYPE ) {
529- await this . processAttachment ( testUuid , hookStep . uuid , attachment ) ;
530- continue ;
531- }
532-
533499 if ( targetStack ) {
534500 const stepResult = targetStack . findStepByUuid ( hookStep . uuid ) ;
535501 if ( stepResult ) {
@@ -541,9 +507,19 @@ export class AllureReporter implements ReporterV2 {
541507 } ) ;
542508 }
543509 }
510+ continue ;
511+ }
512+
513+ if ( stepInfo ?. stepUuid ) {
514+ await this . processAttachment ( testUuid , stepInfo . stepUuid , attachment ) ;
515+ continue ;
544516 }
517+
518+ await this . processAttachment ( testUuid , undefined , attachment ) ;
545519 }
546520
521+ // FIXME: temp logic for labels override, we need it here to keep the reporter compatible with v2 API
522+ // in next iterations we need to implement the logic for every javascript integration
547523 this . allureRuntime ! . updateTest ( testUuid , ( testResult ) => {
548524 const mappedLabels = testResult . labels . reduce < Record < string , Label [ ] > > ( ( acc , label ) => {
549525 if ( ! acc [ label . name ] ) {
0 commit comments