Class RunUtils

java.lang.Object
io.karatelabs.core.RunUtils

public final class RunUtils extends Object
Shared helpers for run-event JSON shaping — cross-run-stable slug computation and tag-text extraction. Used by FeatureRunEvent, ScenarioRunEvent, and OutlineRunEvent to keep identity + tag fields consistent across the JSONL stream so receivers can stitch by slug without re-reading source files.

Slug resolution:

  1. Feature → its relative path.
  2. Named scenario → <feature-path>:<scenario-name>.
  3. Unnamed scenario → <feature-path>::L<line>.
  4. Outline → name-based against feature path (line fallback).
  5. Outline-example → <outline-slug>:<exampleIndex>.

Rename / refactor stability is an opt-in via the author-set __id variable (a sibling of __row/__num), captured and applied in ScenarioRunEvent: when a scenario binds a non-blank __id it overrides the derived slug verbatim. An earlier design instead used an @id=<value> tag as a first-precedence override; that was removed because @id= is a generic tag many teams already use for their own conventions (ticket IDs, story keys, internal nomenclature), and silently co-opting it into our cross-run-identity model coupled their tag conventions to our data model in a way they never asked for. __id is explicit — the author binds it on purpose — so it carries no such surprise.

  • Method Details

    • featureSlug

      public static String featureSlug(Feature feature)
    • effectiveSlug

      public static String effectiveSlug(String stableId, Scenario scenario, Feature feature)
      The scenario's effective identity for the wire: a non-blank author-set stableId (__id) wins verbatim; otherwise the slug derives from feature path + scenario name. One rule, shared by every emit site — ScenarioResult.toJson(), ScenarioRunEvent.toJson() and karate.scenario.slug (KarateJsBase) — so they can never diverge. stableId is resolved once, while the engine is live, by ScenarioRuntime.resolveStableId().
    • scenarioIdentity

      public static Map<String,Object> scenarioIdentity(Scenario scenario, String stableId)
      The scenario's shared identity + metadata fields — name, slug, description, line, section/example indices, and example data. One routine behind both the karate.scenario JS API (KarateJsBase.getScenarioData) and the ScenarioResult JSONL / report payload (ScenarioResult.toJson()), so the two can never drift. Callers layer their purpose-specific fields on the returned (mutable) map: ScenarioResult adds status / timing / steps / tags; ScenarioRunEvent keeps its own envelope (feature path, callDepth, redacted description, outline stitching) since those are wire-only. stableId is the resolved __id (null → derive the slug). description is the raw value; redaction is a wire concern applied by the event, not here.
    • scenarioSlug

      public static String scenarioSlug(Scenario scenario, Feature feature)
    • outlineSlug

      public static String outlineSlug(ScenarioOutline outline, Feature feature)
    • parentOutline

      public static ScenarioOutline parentOutline(Scenario scenario)
      Returns the parent ScenarioOutline if the scenario was generated from one, else null.
    • tagTexts

      public static List<String> tagTexts(List<Tag> tags)
    • mergedTagTexts

      public static List<String> mergedTagTexts(List<Tag> a, List<Tag> b)
      Concatenate text from two Tag lists (feature-level + outline-level for outlines that don't expose getTagsEffective).