55import com .intuit .karate .RuntimeHook ;
66import com .intuit .karate .Suite ;
77import com .intuit .karate .core .ScenarioRuntime ;
8+ import com .intuit .karate .core .Step ;
9+ import com .intuit .karate .core .StepResult ;
810import io .testomat .core .exception .ReportTestResultException ;
911import io .testomat .core .model .TestResult ;
1012import io .testomat .core .runmanager .GlobalRunManager ;
13+ import io .testomat .core .step .StepStorage ;
14+ import io .testomat .core .step .StepTimer ;
15+ import io .testomat .core .step .TestStep ;
16+ import io .testomat .karate .adapter .CustomKarateEngineAdapter ;
17+ import io .testomat .karate .adapter .KarateEngineAdapter ;
1118import io .testomat .karate .constructor .KarateTestResultConstructor ;
1219import io .testomat .karate .exception .KarateHookException ;
20+ import org .slf4j .Logger ;
21+ import org .slf4j .LoggerFactory ;
1322
1423/**
1524 * Runtime hook for integrating Karate test execution with Testomat.io.
16- * Reports Karate test execution results to the Testomat.io platform.
25+ * Reports Karate test execution results to the
26+ * Testomat.io platform.
1727 */
1828public class KarateHook implements RuntimeHook {
1929
30+ private static final Logger log = LoggerFactory .getLogger (KarateHook .class );
31+
32+ private static final String LOG_NEXT_STEP = "log_next_step" ;
33+ private static final String LOG_NEXT_STEP_TITLE = "log_next_step_title" ;
34+ private static final String LOG_STEPS = "LogSteps" ;
35+
2036 private final KarateTestResultConstructor resultConstructor ;
2137 private final FacadeFunctionsHandler functionsHandler ;
2238 private final GlobalRunManager runManager ;
39+ private final KarateEngineAdapter engine ;
2340
2441 public KarateHook (
2542 KarateTestResultConstructor resultConstructor ,
2643 FacadeFunctionsHandler functionsHandler ,
27- GlobalRunManager runManager
44+ GlobalRunManager runManager ,
45+ KarateEngineAdapter engine
2846 ) {
2947 this .resultConstructor = resultConstructor ;
3048 this .functionsHandler = functionsHandler ;
3149 this .runManager = runManager ;
50+ this .engine = engine ;
3251 }
3352
3453 /**
@@ -39,7 +58,8 @@ public KarateHook() {
3958 this (
4059 new KarateTestResultConstructor (),
4160 new FacadeFunctionsHandler (),
42- GlobalRunManager .getInstance ()
61+ GlobalRunManager .getInstance (),
62+ new CustomKarateEngineAdapter ()
4363 );
4464 }
4565
@@ -48,6 +68,51 @@ public void beforeSuite(Suite suite) {
4868 runManager .incrementSuiteCounter ();
4969 }
5070
71+ @ Override
72+ public boolean beforeStep (Step step , ScenarioRuntime sr ) {
73+ boolean isMarked = Boolean .TRUE .equals (engine .getVariable (LOG_NEXT_STEP ));
74+
75+ boolean isDslStep = switch (step .getPrefix () == null ? "" : step .getPrefix ()) {
76+ case "Given" , "When" , "Then" , "And" , "But" -> true ;
77+ default -> false ;
78+ };
79+
80+ boolean logAllSteps = isDslStep && sr .tags .getTags ().contains (LOG_STEPS );
81+
82+ if (logAllSteps || isMarked ) {
83+ engine .setVariable (LOG_NEXT_STEP , false );
84+ String stepId = Thread .currentThread ().getId () + ":" + System .identityHashCode (step );
85+ StepTimer .start (stepId );
86+ }
87+ return true ;
88+ }
89+
90+ @ Override
91+ public void afterStep (StepResult result , ScenarioRuntime sr ) {
92+ Step step = result .getStep ();
93+ String stepId = Thread .currentThread ().getId () + ":" + System .identityHashCode (step );
94+ long durationMillis = StepTimer .stop (stepId );
95+
96+ if (durationMillis != -1 ) {
97+ String stepName = step .getText ();
98+ Object title = engine .getVariable (LOG_NEXT_STEP_TITLE );
99+
100+ if (title != null ) {
101+ stepName = title .toString ();
102+ engine .setVariable (LOG_NEXT_STEP_TITLE , null );
103+ }
104+
105+ TestStep testStep = new TestStep ();
106+ testStep .setCategory ("user" );
107+ testStep .setStepTitle (stepName );
108+ testStep .setDuration (durationMillis );
109+
110+ StepStorage .addStep (testStep );
111+
112+ log .debug ("Step '{}' completed in {} ms" , stepName , durationMillis );
113+ }
114+ }
115+
51116 @ Override
52117 public void afterScenario (ScenarioRuntime sr ) {
53118 if (!runManager .isActive ()) {
0 commit comments