anchor.diff:              reply_to = ReplyTo
           },
   
  -        case should_defer_step_execution(StepMockSpec, TestCtx0) of
  +        case should_defer_step_execution(StepMockSpec, TestCtx1) of
               true ->
  -                monitor_workflow_execution(TestCtx0#test_ctx{deferred_step_phases = maps:update_with(
  +                monitor_workflow_execution(TestCtx1#test_ctx{deferred_step_phases = maps:update_with(
                       StepMockSpec#atm_step_mock_spec.defer_after,
                       fun(RestDeferredStepPhases) -> [StepPhase | RestDeferredStepPhases] end,
                       [StepPhase],
  -                    TestCtx0#test_ctx.deferred_step_phases
  +                    TestCtx1#test_ctx.deferred_step_phases
                   )});
               false ->
  -                monitor_workflow_execution(begin_step_phase_execution(StepPhase, TestCtx0))
  +                monitor_workflow_execution(begin_step_phase_execution(StepPhase, TestCtx1))
           end
  -    after ?PARALLEL_STEP_EXECUTIONS ->  %% TODO handle test hunging
  -%%        ct:pal("ERROR: Atm workflow execution hung"),
  -%%        ?assertEqual(success, failure)
  -
  -        TestCtx1 = assert_expectations_if_changed(TestCtx0),
  -        TestCtx2 = end_pending_step_phase_executions(TestCtx1),
  -
  -        case has_workflow_ended(TestCtx2) of
  -            true ->
  -                ok;
  -            false ->
  -                TestCtx3 = begin_deferred_step_phase_executions_if_possible(TestCtx2),
  -                monitor_workflow_execution(TestCtx3)
  +    after ?AWAIT_OTHER_PARALLEL_PIPELINES_NEXT_STEP_INTERVAL ->
  +        case TestCtx0#test_ctx.test_hung_probes_left of
  +            0 ->
  +                ct:pal("Automation workflow execution test hung after steps: ~p", [
  +                    TestCtx0#test_ctx.executed_step_phases
  +                ]),
  +                ?assertEqual(success, failure);
  +            Num ->
  +                TestCtx1 = TestCtx0#test_ctx{test_hung_probes_left = Num - 1},
  +                TestCtx2 = assert_expectations_if_changed(TestCtx1),
  +                TestCtx3 = end_pending_step_phase_executions(TestCtx2),
  +
  +                case has_workflow_ended(TestCtx3) of
  +                    true ->
  +                        ok;
  +                    false ->
  +                        TestCtx4 = begin_deferred_step_phase_executions_if_possible(TestCtx3),
  +                        monitor_workflow_execution(TestCtx4)
  +                end
           end
       end.
   
  
positive.code:         current_run_num = 1,
          ongoing_incarnations = Incarnations,
          workflow_execution_exp_state = ExpState,
          workflow_execution_exp_state_changed = false
      }).
  
  
  
negative.code: 
      executed_step_phases = [] :: [step_phase_selector()],
      pending_step_phases = [] :: [step_phase()],
      deferred_step_phases = #{} :: #{step_phase_selector() => [step_phase()]},
  
      test_hung_probes_left :: non_neg_integer()
  }).
  -type test_ctx() :: #test_ctx{}.
  
  -define(AWAIT_OTHER_PARALLEL_PIPELINES_NEXT_STEP_INTERVAL, 100).
  -define(TEST_HUNG_MAX_PROBES_NUM, 10).
  
  -define(TEST_PROC_PID_KEY(__ATM_WORKFLOW_EXECUTION_ID),
      {atm_test_runner_process, __ATM_WORKFLOW_EXECUTION_ID}
  