{"version":3,"sources":["../src/reporter.ts","../src/store.ts"],"sourcesContent":["/**\n * Cypress/Mocha reporter for executable-stories.\n * Builds RawRun (formatters schema) from run results + stored story meta, then generates reports.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { StoryMeta } from \"executable-stories-formatters\";\n\nimport {\n  ReportGenerator,\n  canonicalizeRun,\n  readGitSha,\n  readPackageVersion,\n  detectCI,\n  type RawRun,\n  type RawTestCase,\n  type RawAttachment,\n  type RawStepEvent,\n  type RawStatus,\n  type FormatterOptions,\n} from \"executable-stories-formatters\";\n\nimport { getMeta, getAttachments, getAllMeta, getFeature, clearStore } from \"./store\";\n\n// Re-export types from formatters\nexport type {\n  OutputFormat,\n  OutputMode,\n  ColocatedStyle,\n  OutputRule,\n  FormatterOptions,\n} from \"executable-stories-formatters\";\n\n// ============================================================================\n// Reporter Options\n// ============================================================================\n\nexport interface StoryReporterOptions extends FormatterOptions {\n  /** If set, write raw run JSON (schemaVersion 1) to this path for CLI/binary */\n  rawRunPath?: string;\n  /** Spec file path (relative to projectRoot) for this run. If omitted, inferred from stored meta when possible. */\n  specPath?: string;\n  /** Project root. Defaults to process.cwd(). */\n  projectRoot?: string;\n  /**\n   * Declare how much of each spec this run covered.\n   *\n   * Cypress has no built-in name filter — narrowing by title needs\n   * @cypress/grep, which the reporter cannot observe — so unlike the Vitest,\n   * Jest and Playwright adapters this cannot be detected. Left unset the run\n   * states no scope, and consumers keep what it did not report rather than\n   * retiring it on a guess.\n   *\n   * Set `\"filtered\"` when running under @cypress/grep. Set `\"full\"` only when\n   * you know the run covered whole specs, since that is what permits a\n   * scenario to be removed from the accumulated report.\n   */\n  runScope?: \"full\" | \"filtered\";\n}\n\n// ============================================================================\n// Mocha Runner / Test types (minimal for reporter)\n// ============================================================================\n\ninterface MochaSuite {\n  title: string;\n  suites: MochaSuite[];\n  tests: MochaTest[];\n  parent?: MochaSuite;\n}\n\ninterface MochaTest {\n  title: string;\n  state?: string;\n  duration?: number;\n  err?: Error & { message?: string; stack?: string };\n  parent?: MochaSuite;\n  /** Mocha marks both `it.skip(...)` and a bodyless `it(\"title\")` as pending. */\n  pending?: boolean;\n  /** Absent only when the test was declared with no callback at all. */\n  fn?: unknown;\n}\n\n/**\n * A bodyless `it(\"title\")` is Mocha's way of writing down behaviour that does\n * not exist yet, which is what a planned scenario is. `it.skip(title, fn)` is\n * also pending but keeps its body: that means \"do not run this now\", a\n * different claim, so it stays a skip.\n */\nfunction isPlannedTest(test: MochaTest): boolean {\n  return test.pending === true && test.fn === undefined;\n}\n\ninterface MochaRunner {\n  suite: MochaSuite;\n  startTime?: number;\n  on?(event: string, callback: () => void): void;\n}\n\nfunction getTitlePath(test: MochaTest): string[] {\n  const path: string[] = [];\n  let current: MochaSuite | MochaTest | undefined = test;\n  while (current) {\n    const title = \"title\" in current ? current.title : \"\";\n    if (title) path.unshift(title);\n    current = \"parent\" in current ? current.parent : undefined;\n  }\n  return path;\n}\n\nfunction collectTests(suite: MochaSuite): MochaTest[] {\n  const tests = [...suite.tests];\n  for (const s of suite.suites) {\n    tests.push(...collectTests(s));\n  }\n  return tests;\n}\n\nfunction mapCypressStateToRaw(state: string | undefined): RawStatus {\n  switch (state) {\n    case \"passed\":\n      return \"pass\";\n    case \"failed\":\n      return \"fail\";\n    case \"pending\":\n      return \"skip\";\n    default:\n      return \"unknown\";\n  }\n}\n\n// ============================================================================\n// Reporter Implementation\n// ============================================================================\n\nconst DEFAULT_OPTIONS: Partial<StoryReporterOptions> = {\n  projectRoot: process.cwd(),\n};\n\n/**\n * Create a Mocha reporter function that Cypress can use (--reporter path/to/reporter).\n * Cypress passes (runner, reporterOptions) with reporterOptions as the second argument directly.\n * Also supports options.reporterOptions for wrapped usage.\n */\nfunction createReporter(\n  runner: MochaRunner,\n  options: StoryReporterOptions | { reporterOptions?: StoryReporterOptions } = {}\n) {\n  const reporterOpts =\n    \"reporterOptions\" in options && options.reporterOptions\n      ? options.reporterOptions\n      : (options as StoryReporterOptions);\n  const opts: StoryReporterOptions = { ...DEFAULT_OPTIONS, ...reporterOpts };\n  const projectRoot = opts.projectRoot ?? process.cwd();\n  const specPath = opts.specPath ?? \"unknown\";\n  const startTime = runner.startTime ?? Date.now();\n\n  runner.suite && runner.on?.(\"end\", () => {\n    const tests = collectTests(runner.suite);\n    const rawTestCases: RawTestCase[] = [];\n\n    // If specPath not provided, infer from first stored meta (all stored entries are for this spec in a single-spec run)\n    const effectiveSpecPath =\n      specPath !== \"unknown\"\n        ? specPath\n        : (() => {\n            const all = getAllMeta();\n            return all.length > 0 ? all[0].specRelative : \"unknown\";\n          })();\n\n    // Bodyless tests never run story.init(), so they are collected separately\n    // and only kept when the spec has real story tests to sit alongside.\n    const plannedTests: MochaTest[] = [];\n\n    for (const test of tests) {\n      const titlePath = getTitlePath(test);\n      const meta = getMeta(effectiveSpecPath, titlePath);\n      if (!meta) {\n        if (isPlannedTest(test)) plannedTests.push(test);\n        continue; // only document tests that used story.init()\n      }\n\n      const status = mapCypressStateToRaw(test.state);\n\n      // Map stored attachments to RawAttachment[]\n      const storedAttachments = getAttachments(effectiveSpecPath, titlePath);\n      const attachments: RawAttachment[] | undefined = storedAttachments?.map((a) => ({\n        name: a.name,\n        mediaType: a.mediaType,\n        path: a.path,\n        body: typeof a.body === 'string' ? a.body : a.body instanceof Buffer ? a.body.toString('base64') : undefined,\n        encoding: a.encoding ?? (a.body instanceof Buffer ? 'BASE64' : undefined),\n        charset: a.charset,\n        fileName: a.fileName,\n        stepIndex: a.stepIndex,\n        stepId: a.stepId,\n      }));\n\n      // Extract step events (timing)\n      const stepEvents: RawStepEvent[] = meta.steps\n        .filter((s: { durationMs?: number }) => s.durationMs !== undefined)\n        .map((s: { durationMs?: number; text: string }, i: number) => ({\n          index: i,\n          title: s.text,\n          durationMs: s.durationMs,\n        }));\n\n      rawTestCases.push({\n        title: meta.scenario,\n        titlePath: meta.suitePath ? [...meta.suitePath, meta.scenario] : [meta.scenario],\n        story: meta,\n        sourceFile: effectiveSpecPath,\n        sourceLine: 1,\n        status,\n        durationMs: test.duration,\n        error: test.err\n          ? { message: test.err.message, stack: test.err.stack }\n          : undefined,\n        attachments: attachments && attachments.length > 0 ? attachments : undefined,\n        stepEvents: stepEvents.length > 0 ? stepEvents : undefined,\n        retry: 0,\n        retries: 0,\n      });\n    }\n\n    if (rawTestCases.length === 0) {\n      clearStore();\n      return;\n    }\n\n    for (const test of plannedTests) {\n      const titlePath = getTitlePath(test);\n      const suitePath = titlePath.slice(0, -1);\n      rawTestCases.push({\n        title: test.title,\n        titlePath,\n        story: {\n          scenario: test.title,\n          steps: [],\n          ...(suitePath.length > 0 ? { suitePath } : {}),\n        },\n        sourceFile: effectiveSpecPath,\n        sourceLine: 1,\n        status: \"todo\",\n        durationMs: 0,\n        retry: 0,\n        retries: 0,\n      });\n    }\n\n    const includeMetadata = opts.markdown?.includeMetadata ?? true;\n    const declaredFeature = getFeature(effectiveSpecPath);\n    const rawRun: RawRun = {\n      testCases: rawTestCases,\n      ...(declaredFeature\n        ? { features: [{ ...declaredFeature, sourceFile: effectiveSpecPath }] }\n        : {}),\n      startedAtMs: startTime,\n      finishedAtMs: Date.now(),\n      projectRoot,\n      packageVersion: includeMetadata ? readPackageVersion(projectRoot) : undefined,\n      gitSha: includeMetadata ? readGitSha(projectRoot) : undefined,\n      ci: detectCI(),\n      ...(opts.runScope ? { runScope: opts.runScope } : {}),\n    };\n\n    const rawRunPath = opts.rawRunPath;\n    if (rawRunPath) {\n      const absolutePath = path.isAbsolute(rawRunPath)\n        ? rawRunPath\n        : path.join(projectRoot, rawRunPath);\n      const dir = path.dirname(absolutePath);\n      if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n      fs.writeFileSync(absolutePath, JSON.stringify({ schemaVersion: 1, ...rawRun }, null, 2), \"utf8\");\n    }\n\n    const canonicalRun = canonicalizeRun(rawRun);\n    const generator = new ReportGenerator(opts);\n    generator.generate(canonicalRun).catch((err) => {\n      console.error(\"Failed to generate reports:\", err);\n    });\n\n    clearStore();\n  });\n}\n\n/**\n * Alternative: build RawRun from Cypress Module API results + stored meta.\n * Use this when not using the Mocha reporter (e.g. in after:run plugin).\n * Call recordMeta via plugin during the run, then call this with cypress.run() result.\n */\nexport interface CypressRunResultTest {\n  title: string[];\n  state?: string;\n  displayError?: string;\n  duration?: number;\n  attempts?: Array<{\n    state?: string;\n    duration?: number;\n    error?: { message?: string; stack?: string };\n  }>;\n}\n\nexport interface CypressRunResultRun {\n  spec?: { relative?: string; absolute?: string };\n  tests?: CypressRunResultTest[];\n}\n\nexport interface CypressRunResult {\n  runs?: CypressRunResultRun[];\n  config?: { projectRoot?: string };\n}\n\nexport function buildRawRunFromCypressResult(\n  result: CypressRunResult,\n  options: StoryReporterOptions = {}\n): RawRun {\n  const projectRoot = options.projectRoot ?? result.config?.projectRoot ?? process.cwd();\n  const rawTestCases: RawTestCase[] = [];\n\n  for (const run of result.runs ?? []) {\n    const specRelative = run.spec?.relative ?? \"unknown\";\n    for (const test of run.tests ?? []) {\n      const titlePath = test.title ?? [];\n      const meta = getMeta(specRelative, titlePath);\n      if (!meta) continue;\n\n      const lastAttempt = test.attempts?.length\n        ? test.attempts[test.attempts.length - 1]\n        : undefined;\n      const state = lastAttempt?.state ?? test.state;\n      const err = lastAttempt?.error ?? (test.displayError ? { message: test.displayError } : undefined);\n      const duration = lastAttempt?.duration ?? test.duration;\n\n      rawTestCases.push({\n        title: meta.scenario,\n        titlePath: meta.suitePath ? [...meta.suitePath, meta.scenario] : [meta.scenario],\n        story: meta,\n        sourceFile: specRelative,\n        sourceLine: 1,\n        status: mapCypressStateToRaw(state),\n        durationMs: duration,\n        error: err ? { message: err.message, stack: err.stack } : undefined,\n      });\n    }\n  }\n\n  const includeMetadata = options.markdown?.includeMetadata ?? true;\n  return {\n    testCases: rawTestCases,\n    startedAtMs: undefined,\n    finishedAtMs: Date.now(),\n    projectRoot,\n    packageVersion: includeMetadata ? readPackageVersion(projectRoot) : undefined,\n    gitSha: includeMetadata ? readGitSha(projectRoot) : undefined,\n    ci: detectCI(),\n    ...(options.runScope ? { runScope: options.runScope } : {}),\n  };\n}\n\n/**\n * Generate reports from a RawRun (e.g. after buildRawRunFromCypressResult).\n */\nexport async function generateReportsFromRawRun(\n  rawRun: RawRun,\n  options: FormatterOptions\n): Promise<void> {\n  if (rawRun.testCases.length === 0) return;\n  const canonicalRun = canonicalizeRun(rawRun);\n  const generator = new ReportGenerator(options);\n  await generator.generate(canonicalRun);\n}\n\nexport default createReporter;\n","/**\n * Node-only store for story meta sent from the browser via cy.task.\n * Plugin writes; reporter reads. Keyed by spec + titlePath for merging with run results.\n */\n\nimport type { StoryMeta, ScopedAttachment, RecordMetaPayload, FeatureInput } from \"./types\";\n\nexport interface StoredMeta {\n  specRelative: string;\n  titlePath: string[];\n  meta: StoryMeta;\n  attachments?: ScopedAttachment[];\n}\n\nfunction key(specRelative: string, titlePath: string[]): string {\n  return `${specRelative}\\0${titlePath.join(\"\\0\")}`;\n}\n\nconst store = new Map<string, StoredMeta>();\nconst features = new Map<string, FeatureInput>();\n\nexport function recordMeta(payload: RecordMetaPayload): null {\n  store.set(key(payload.specRelative, payload.titlePath), {\n    specRelative: payload.specRelative,\n    titlePath: payload.titlePath,\n    meta: payload.meta,\n    attachments: payload.attachments,\n  });\n  if (payload.feature?.title) features.set(payload.specRelative, payload.feature);\n  return null;\n}\n\n/** The feature declared by a spec, if it declared one. */\nexport function getFeature(specRelative: string): FeatureInput | undefined {\n  return features.get(specRelative);\n}\n\nexport function getAttachments(specRelative: string, titlePath: string[]): ScopedAttachment[] | undefined {\n  return store.get(key(specRelative, titlePath))?.attachments;\n}\n\nexport function getMeta(specRelative: string, titlePath: string[]): StoryMeta | undefined {\n  return store.get(key(specRelative, titlePath))?.meta;\n}\n\nexport function getAllMeta(): StoredMeta[] {\n  return Array.from(store.values());\n}\n\nexport function clearStore(): void {\n  store.clear();\n  features.clear();\n}\n"],"mappings":"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","names":["path"]}