autotel-vitest 0.3.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -22,37 +22,38 @@ function ensureCollector() {
22
22
  }
23
23
  return collector;
24
24
  }
25
- var test = vitest.test.extend({
26
- _otelTestSpan: [
27
- async ({ task }, use) => {
28
- ensureCollector();
29
- const tracer = autotel.getTracer(TRACER_NAME, TRACER_VERSION);
30
- const span = tracer.startSpan(`test:${task.name}`, {
31
- attributes: {
32
- "test.name": task.name,
33
- "test.file": task.file?.name ?? "",
34
- "test.suite": task.suite?.name ?? ""
35
- }
36
- });
37
- const ctx = autotel.otelTrace.setSpan(autotel.context.active(), span);
38
- try {
39
- await autotel.context.with(ctx, () => use(span));
40
- } catch (error) {
41
- span.setStatus({ code: autotel.SpanStatusCode.ERROR });
42
- span.recordException(error instanceof Error ? error : new Error(String(error)));
43
- throw error;
44
- } finally {
45
- span.end();
46
- const traceId = span.spanContext().traceId;
47
- const rootSpanId = span.spanContext().spanId;
48
- const spans = collector.drainTrace(traceId, rootSpanId);
49
- if (spans.length > 0) {
50
- task.meta.otelSpans = spans;
51
- }
25
+ var otelTestSpanFixture = [
26
+ async ({ task }, use) => {
27
+ ensureCollector();
28
+ const tracer = autotel.getTracer(TRACER_NAME, TRACER_VERSION);
29
+ const span = tracer.startSpan(`test:${task.name}`, {
30
+ attributes: {
31
+ "test.name": task.name,
32
+ "test.file": task.file?.name ?? "",
33
+ "test.suite": task.suite?.name ?? ""
34
+ }
35
+ });
36
+ const ctx = autotel.otelTrace.setSpan(autotel.context.active(), span);
37
+ try {
38
+ await autotel.context.with(ctx, () => use(span));
39
+ } catch (error) {
40
+ span.setStatus({ code: autotel.SpanStatusCode.ERROR });
41
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
42
+ throw error;
43
+ } finally {
44
+ span.end();
45
+ const traceId = span.spanContext().traceId;
46
+ const rootSpanId = span.spanContext().spanId;
47
+ const spans = collector.drainTrace(traceId, rootSpanId);
48
+ if (spans.length > 0) {
49
+ task.meta.otelSpans = spans;
52
50
  }
53
- },
54
- { auto: true }
55
- ]
51
+ }
52
+ },
53
+ { auto: true }
54
+ ];
55
+ var test = vitest.test.extend({
56
+ _otelTestSpan: otelTestSpanFixture
56
57
  });
57
58
 
58
59
  Object.defineProperty(exports, "afterAll", {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["TestSpanCollector","getAutotelTracerProvider","SimpleSpanProcessor","base","getTracer","otelTrace","otelContext","SpanStatusCode"],"mappings":";;;;;;;;;AA4BA,IAAM,WAAA,GAAc,cAAA;AACpB,IAAM,cAAA,GAAiB,OAAA;AAEvB,IAAI,SAAA,GAAsC,IAAA;AAM1C,SAAS,eAAA,GAAqC;AAC5C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,SAAA,GAAY,IAAIA,mCAAA,EAAkB;AAClC,IAAA,MAAM,WAAWC,gCAAA,EAAyB;AAC1C,IAAA,IAAI,sBAAsB,QAAA,EAAU;AAClC,MAAC,QAAA,CAAyC,gBAAA;AAAA,QACxC,IAAIC,+BAAoB,SAAS;AAAA,OACnC;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,SAAA;AACT;AAEO,IAAM,IAAA,GAAOC,YAAK,MAAA,CAAO;AAAA,EAC9B,aAAA,EAAe;AAAA,IACb,OAAO,EAAE,IAAA,EAAK,EAAG,GAAA,KAAQ;AACvB,MAAA,eAAA,EAAgB;AAChB,MAAA,MAAM,MAAA,GAASC,iBAAA,CAAU,WAAA,EAAa,cAAc,CAAA;AACpD,MAAA,MAAM,OAAO,MAAA,CAAO,SAAA,CAAU,CAAA,KAAA,EAAQ,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI;AAAA,QACjD,UAAA,EAAY;AAAA,UACV,aAAa,IAAA,CAAK,IAAA;AAAA,UAClB,WAAA,EAAa,IAAA,CAAK,IAAA,EAAM,IAAA,IAAQ,EAAA;AAAA,UAChC,YAAA,EAAc,IAAA,CAAK,KAAA,EAAO,IAAA,IAAQ;AAAA;AACpC,OACD,CAAA;AACD,MAAA,MAAM,MAAMC,iBAAA,CAAU,OAAA,CAAQC,eAAA,CAAY,MAAA,IAAU,IAAI,CAAA;AACxD,MAAA,IAAI;AACF,QAAA,MAAMA,gBAAY,IAAA,CAAK,GAAA,EAAK,MAAM,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,MAC7C,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAMC,sBAAA,CAAe,OAAO,CAAA;AAC7C,QAAA,IAAA,CAAK,eAAA,CAAgB,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAC9E,QAAA,MAAM,KAAA;AAAA,MACR,CAAA,SAAE;AACA,QAAA,IAAA,CAAK,GAAA,EAAI;AACT,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,WAAA,EAAY,CAAE,OAAA;AACnC,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,WAAA,EAAY,CAAE,MAAA;AACtC,QAAA,MAAM,KAAA,GAAQ,SAAA,CAAW,UAAA,CAAW,OAAA,EAAS,UAAU,CAAA;AACvD,QAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,UAAC,IAAA,CAAK,KAAiC,SAAA,GAAY,KAAA;AAAA,QACrD;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,EAAE,MAAM,IAAA;AAAK;AAEjB,CAAC","file":"index.cjs","sourcesContent":["/**\n * autotel-vitest\n *\n * Vitest fixture that creates one OTel span per test so all autotel-instrumented\n * code executed during a test automatically creates child spans under it;\n * making every test run filterable in your OTLP backend.\n *\n * @example\n * // vitest.config.ts: globalSetup calls init({ service: 'unit-tests' })\n * // In spec:\n * import { test, expect } from 'autotel-vitest';\n * test('creates user', async () => {\n * await userService.createUser({ email: 'test@example.com' });\n * // All trace()/span() calls become children of the test span\n * });\n */\n\nimport { test as base } from 'vitest';\nimport {\n getTracer,\n getAutotelTracerProvider,\n context as otelContext,\n otelTrace,\n SpanStatusCode,\n} from 'autotel';\nimport { TestSpanCollector } from 'autotel/test-span-collector';\nimport { SimpleSpanProcessor } from 'autotel/processors';\n\nconst TRACER_NAME = 'vitest-tests';\nconst TRACER_VERSION = '0.1.0';\n\nlet collector: TestSpanCollector | null = null;\n\ninterface TracerProviderWithProcessor {\n addSpanProcessor(processor: unknown): void;\n}\n\nfunction ensureCollector(): TestSpanCollector {\n if (!collector) {\n collector = new TestSpanCollector();\n const provider = getAutotelTracerProvider();\n if ('addSpanProcessor' in provider) {\n (provider as TracerProviderWithProcessor).addSpanProcessor(\n new SimpleSpanProcessor(collector),\n );\n }\n }\n return collector;\n}\n\nexport const test = base.extend({\n _otelTestSpan: [\n async ({ task }, use) => {\n ensureCollector();\n const tracer = getTracer(TRACER_NAME, TRACER_VERSION);\n const span = tracer.startSpan(`test:${task.name}`, {\n attributes: {\n 'test.name': task.name,\n 'test.file': task.file?.name ?? '',\n 'test.suite': task.suite?.name ?? '',\n },\n });\n const ctx = otelTrace.setSpan(otelContext.active(), span);\n try {\n await otelContext.with(ctx, () => use(span));\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error instanceof Error ? error : new Error(String(error)));\n throw error;\n } finally {\n span.end();\n const traceId = span.spanContext().traceId;\n const rootSpanId = span.spanContext().spanId;\n const spans = collector!.drainTrace(traceId, rootSpanId);\n if (spans.length > 0) {\n (task.meta as Record<string, unknown>).otelSpans = spans;\n }\n }\n },\n { auto: true },\n ],\n});\n\nexport { expect, describe, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';\n\n// Re-export all autotel/testing utilities\nexport {\n createTraceCollector,\n assertTraceCreated,\n assertTraceSucceeded,\n assertTraceFailed,\n assertNoErrors,\n assertTraceDuration,\n waitForTrace,\n getTraceDuration,\n createMockLogger,\n type TraceCollector,\n type TestSpan,\n type LogCollector,\n type LogEntry,\n} from 'autotel/testing';\n\n// Re-export trace context helpers for DX convenience\nexport {\n getTraceContext,\n resolveTraceUrl,\n isTracing,\n enrichWithTraceContext,\n} from 'autotel';\n\nexport type { OtelTraceContext } from 'autotel';\n"]}
1
+ {"version":3,"sources":["../src/fixture.ts","../src/index.ts"],"names":["TestSpanCollector","getAutotelTracerProvider","SimpleSpanProcessor","getTracer","otelTrace","otelContext","SpanStatusCode","base"],"mappings":";;;;;;;;;AAUA,IAAM,WAAA,GAAc,cAAA;AACpB,IAAM,cAAA,GAAiB,OAAA;AAEvB,IAAI,SAAA,GAAsC,IAAA;AAM1C,SAAS,eAAA,GAAqC;AAC5C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,SAAA,GAAY,IAAIA,mCAAA,EAAkB;AAClC,IAAA,MAAM,WAAWC,gCAAA,EAAyB;AAC1C,IAAA,IAAI,sBAAsB,QAAA,EAAU;AAClC,MAAC,QAAA,CAAyC,gBAAA;AAAA,QACxC,IAAIC,+BAAoB,SAAS;AAAA,OACnC;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,SAAA;AACT;AAOO,IAAM,mBAAA,GAAuD;AAAA,EAClE,OACE,EAAE,IAAA,EAAK,EACP,GAAA,KACG;AACH,IAAA,eAAA,EAAgB;AAChB,IAAA,MAAM,MAAA,GAASC,iBAAA,CAAU,WAAA,EAAa,cAAc,CAAA;AACpD,IAAA,MAAM,OAAO,MAAA,CAAO,SAAA,CAAU,CAAA,KAAA,EAAQ,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI;AAAA,MACjD,UAAA,EAAY;AAAA,QACV,aAAa,IAAA,CAAK,IAAA;AAAA,QAClB,WAAA,EAAa,IAAA,CAAK,IAAA,EAAM,IAAA,IAAQ,EAAA;AAAA,QAChC,YAAA,EAAc,IAAA,CAAK,KAAA,EAAO,IAAA,IAAQ;AAAA;AACpC,KACD,CAAA;AACD,IAAA,MAAM,MAAMC,iBAAA,CAAU,OAAA,CAAQC,eAAA,CAAY,MAAA,IAAU,IAAI,CAAA;AACxD,IAAA,IAAI;AACF,MAAA,MAAMA,gBAAY,IAAA,CAAK,GAAA,EAAK,MAAM,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,IAC7C,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAMC,sBAAA,CAAe,OAAO,CAAA;AAC7C,MAAA,IAAA,CAAK,eAAA,CAAgB,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAC9E,MAAA,MAAM,KAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,GAAA,EAAI;AACT,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,WAAA,EAAY,CAAE,OAAA;AACnC,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,WAAA,EAAY,CAAE,MAAA;AACtC,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAW,UAAA,CAAW,OAAA,EAAS,UAAU,CAAA;AACvD,MAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,QAAC,IAAA,CAAK,KAAiC,SAAA,GAAY,KAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAA;AAAA,EACA,EAAE,MAAM,IAAA;AACV,CAAA;AChDO,IAAM,IAAA,GAAOC,YAAK,MAAA,CAAO;AAAA,EAC9B,aAAA,EAAe;AACjB,CAAC","file":"index.cjs","sourcesContent":["import {\n getTracer,\n getAutotelTracerProvider,\n context as otelContext,\n otelTrace,\n SpanStatusCode,\n} from 'autotel';\nimport { TestSpanCollector } from 'autotel/test-span-collector';\nimport { SimpleSpanProcessor } from 'autotel/processors';\n\nconst TRACER_NAME = 'vitest-tests';\nconst TRACER_VERSION = '0.1.0';\n\nlet collector: TestSpanCollector | null = null;\n\ninterface TracerProviderWithProcessor {\n addSpanProcessor(processor: unknown): void;\n}\n\nfunction ensureCollector(): TestSpanCollector {\n if (!collector) {\n collector = new TestSpanCollector();\n const provider = getAutotelTracerProvider();\n if ('addSpanProcessor' in provider) {\n (provider as TracerProviderWithProcessor).addSpanProcessor(\n new SimpleSpanProcessor(collector),\n );\n }\n }\n return collector;\n}\n\nexport type OtelFixtureFn = (\n args: { task: { name: string; file?: { name: string }; suite?: { name: string }; meta: Record<string, unknown> } },\n use: (span: unknown) => Promise<void>,\n) => Promise<void>;\n\nexport const otelTestSpanFixture: [OtelFixtureFn, { auto: true }] = [\n async (\n { task }: { task: { name: string; file?: { name: string }; suite?: { name: string }; meta: Record<string, unknown> } },\n use: (span: unknown) => Promise<void>,\n ) => {\n ensureCollector();\n const tracer = getTracer(TRACER_NAME, TRACER_VERSION);\n const span = tracer.startSpan(`test:${task.name}`, {\n attributes: {\n 'test.name': task.name,\n 'test.file': task.file?.name ?? '',\n 'test.suite': task.suite?.name ?? '',\n },\n });\n const ctx = otelTrace.setSpan(otelContext.active(), span);\n try {\n await otelContext.with(ctx, () => use(span));\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error instanceof Error ? error : new Error(String(error)));\n throw error;\n } finally {\n span.end();\n const traceId = span.spanContext().traceId;\n const rootSpanId = span.spanContext().spanId;\n const spans = collector!.drainTrace(traceId, rootSpanId);\n if (spans.length > 0) {\n (task.meta as Record<string, unknown>).otelSpans = spans;\n }\n }\n },\n { auto: true },\n];\n","/**\n * autotel-vitest\n *\n * Vitest fixture that creates one OTel span per test so all autotel-instrumented\n * code executed during a test automatically creates child spans under it;\n * making every test run filterable in your OTLP backend.\n *\n * @example\n * // vitest.config.ts: globalSetup calls init({ service: 'unit-tests' })\n * // In spec:\n * import { test, expect } from 'autotel-vitest';\n * test('creates user', async () => {\n * await userService.createUser({ email: 'test@example.com' });\n * // All trace()/span() calls become children of the test span\n * });\n */\n\nimport { test as base } from 'vitest';\nimport { otelTestSpanFixture } from './fixture';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const test = base.extend({\n _otelTestSpan: otelTestSpanFixture as any,\n});\n\nexport { expect, describe, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';\n\n// Re-export all autotel/testing utilities\nexport {\n createTraceCollector,\n assertTraceCreated,\n assertTraceSucceeded,\n assertTraceFailed,\n assertNoErrors,\n assertTraceDuration,\n waitForTrace,\n getTraceDuration,\n createMockLogger,\n type TraceCollector,\n type TestSpan,\n type LogCollector,\n type LogEntry,\n} from 'autotel/testing';\n\n// Re-export trace context helpers for DX convenience\nexport {\n getTraceContext,\n resolveTraceUrl,\n isTracing,\n enrichWithTraceContext,\n} from 'autotel';\n\nexport type { OtelTraceContext } from 'autotel';\n"]}
package/dist/index.d.cts CHANGED
@@ -19,8 +19,6 @@ export { OtelTraceContext, enrichWithTraceContext, getTraceContext, isTracing, r
19
19
  * // All trace()/span() calls become children of the test span
20
20
  * });
21
21
  */
22
- declare const test: vitest.TestAPI<{
23
- _otelTestSpan: unknown;
24
- }>;
22
+ declare const test: vitest.TestAPI<Record<string, any> & object>;
25
23
 
26
24
  export { test };
package/dist/index.d.ts CHANGED
@@ -19,8 +19,6 @@ export { OtelTraceContext, enrichWithTraceContext, getTraceContext, isTracing, r
19
19
  * // All trace()/span() calls become children of the test span
20
20
  * });
21
21
  */
22
- declare const test: vitest.TestAPI<{
23
- _otelTestSpan: unknown;
24
- }>;
22
+ declare const test: vitest.TestAPI<Record<string, any> & object>;
25
23
 
26
24
  export { test };
package/dist/index.js CHANGED
@@ -22,37 +22,38 @@ function ensureCollector() {
22
22
  }
23
23
  return collector;
24
24
  }
25
- var test = test$1.extend({
26
- _otelTestSpan: [
27
- async ({ task }, use) => {
28
- ensureCollector();
29
- const tracer = getTracer(TRACER_NAME, TRACER_VERSION);
30
- const span = tracer.startSpan(`test:${task.name}`, {
31
- attributes: {
32
- "test.name": task.name,
33
- "test.file": task.file?.name ?? "",
34
- "test.suite": task.suite?.name ?? ""
35
- }
36
- });
37
- const ctx = otelTrace.setSpan(context.active(), span);
38
- try {
39
- await context.with(ctx, () => use(span));
40
- } catch (error) {
41
- span.setStatus({ code: SpanStatusCode.ERROR });
42
- span.recordException(error instanceof Error ? error : new Error(String(error)));
43
- throw error;
44
- } finally {
45
- span.end();
46
- const traceId = span.spanContext().traceId;
47
- const rootSpanId = span.spanContext().spanId;
48
- const spans = collector.drainTrace(traceId, rootSpanId);
49
- if (spans.length > 0) {
50
- task.meta.otelSpans = spans;
51
- }
25
+ var otelTestSpanFixture = [
26
+ async ({ task }, use) => {
27
+ ensureCollector();
28
+ const tracer = getTracer(TRACER_NAME, TRACER_VERSION);
29
+ const span = tracer.startSpan(`test:${task.name}`, {
30
+ attributes: {
31
+ "test.name": task.name,
32
+ "test.file": task.file?.name ?? "",
33
+ "test.suite": task.suite?.name ?? ""
34
+ }
35
+ });
36
+ const ctx = otelTrace.setSpan(context.active(), span);
37
+ try {
38
+ await context.with(ctx, () => use(span));
39
+ } catch (error) {
40
+ span.setStatus({ code: SpanStatusCode.ERROR });
41
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
42
+ throw error;
43
+ } finally {
44
+ span.end();
45
+ const traceId = span.spanContext().traceId;
46
+ const rootSpanId = span.spanContext().spanId;
47
+ const spans = collector.drainTrace(traceId, rootSpanId);
48
+ if (spans.length > 0) {
49
+ task.meta.otelSpans = spans;
52
50
  }
53
- },
54
- { auto: true }
55
- ]
51
+ }
52
+ },
53
+ { auto: true }
54
+ ];
55
+ var test = test$1.extend({
56
+ _otelTestSpan: otelTestSpanFixture
56
57
  });
57
58
 
58
59
  export { test };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["base","otelContext"],"mappings":";;;;;;;;;AA4BA,IAAM,WAAA,GAAc,cAAA;AACpB,IAAM,cAAA,GAAiB,OAAA;AAEvB,IAAI,SAAA,GAAsC,IAAA;AAM1C,SAAS,eAAA,GAAqC;AAC5C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,SAAA,GAAY,IAAI,iBAAA,EAAkB;AAClC,IAAA,MAAM,WAAW,wBAAA,EAAyB;AAC1C,IAAA,IAAI,sBAAsB,QAAA,EAAU;AAClC,MAAC,QAAA,CAAyC,gBAAA;AAAA,QACxC,IAAI,oBAAoB,SAAS;AAAA,OACnC;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,SAAA;AACT;AAEO,IAAM,IAAA,GAAOA,OAAK,MAAA,CAAO;AAAA,EAC9B,aAAA,EAAe;AAAA,IACb,OAAO,EAAE,IAAA,EAAK,EAAG,GAAA,KAAQ;AACvB,MAAA,eAAA,EAAgB;AAChB,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,WAAA,EAAa,cAAc,CAAA;AACpD,MAAA,MAAM,OAAO,MAAA,CAAO,SAAA,CAAU,CAAA,KAAA,EAAQ,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI;AAAA,QACjD,UAAA,EAAY;AAAA,UACV,aAAa,IAAA,CAAK,IAAA;AAAA,UAClB,WAAA,EAAa,IAAA,CAAK,IAAA,EAAM,IAAA,IAAQ,EAAA;AAAA,UAChC,YAAA,EAAc,IAAA,CAAK,KAAA,EAAO,IAAA,IAAQ;AAAA;AACpC,OACD,CAAA;AACD,MAAA,MAAM,MAAM,SAAA,CAAU,OAAA,CAAQC,OAAA,CAAY,MAAA,IAAU,IAAI,CAAA;AACxD,MAAA,IAAI;AACF,QAAA,MAAMA,QAAY,IAAA,CAAK,GAAA,EAAK,MAAM,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,MAC7C,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,cAAA,CAAe,OAAO,CAAA;AAC7C,QAAA,IAAA,CAAK,eAAA,CAAgB,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAC9E,QAAA,MAAM,KAAA;AAAA,MACR,CAAA,SAAE;AACA,QAAA,IAAA,CAAK,GAAA,EAAI;AACT,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,WAAA,EAAY,CAAE,OAAA;AACnC,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,WAAA,EAAY,CAAE,MAAA;AACtC,QAAA,MAAM,KAAA,GAAQ,SAAA,CAAW,UAAA,CAAW,OAAA,EAAS,UAAU,CAAA;AACvD,QAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,UAAC,IAAA,CAAK,KAAiC,SAAA,GAAY,KAAA;AAAA,QACrD;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,EAAE,MAAM,IAAA;AAAK;AAEjB,CAAC","file":"index.js","sourcesContent":["/**\n * autotel-vitest\n *\n * Vitest fixture that creates one OTel span per test so all autotel-instrumented\n * code executed during a test automatically creates child spans under it;\n * making every test run filterable in your OTLP backend.\n *\n * @example\n * // vitest.config.ts: globalSetup calls init({ service: 'unit-tests' })\n * // In spec:\n * import { test, expect } from 'autotel-vitest';\n * test('creates user', async () => {\n * await userService.createUser({ email: 'test@example.com' });\n * // All trace()/span() calls become children of the test span\n * });\n */\n\nimport { test as base } from 'vitest';\nimport {\n getTracer,\n getAutotelTracerProvider,\n context as otelContext,\n otelTrace,\n SpanStatusCode,\n} from 'autotel';\nimport { TestSpanCollector } from 'autotel/test-span-collector';\nimport { SimpleSpanProcessor } from 'autotel/processors';\n\nconst TRACER_NAME = 'vitest-tests';\nconst TRACER_VERSION = '0.1.0';\n\nlet collector: TestSpanCollector | null = null;\n\ninterface TracerProviderWithProcessor {\n addSpanProcessor(processor: unknown): void;\n}\n\nfunction ensureCollector(): TestSpanCollector {\n if (!collector) {\n collector = new TestSpanCollector();\n const provider = getAutotelTracerProvider();\n if ('addSpanProcessor' in provider) {\n (provider as TracerProviderWithProcessor).addSpanProcessor(\n new SimpleSpanProcessor(collector),\n );\n }\n }\n return collector;\n}\n\nexport const test = base.extend({\n _otelTestSpan: [\n async ({ task }, use) => {\n ensureCollector();\n const tracer = getTracer(TRACER_NAME, TRACER_VERSION);\n const span = tracer.startSpan(`test:${task.name}`, {\n attributes: {\n 'test.name': task.name,\n 'test.file': task.file?.name ?? '',\n 'test.suite': task.suite?.name ?? '',\n },\n });\n const ctx = otelTrace.setSpan(otelContext.active(), span);\n try {\n await otelContext.with(ctx, () => use(span));\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error instanceof Error ? error : new Error(String(error)));\n throw error;\n } finally {\n span.end();\n const traceId = span.spanContext().traceId;\n const rootSpanId = span.spanContext().spanId;\n const spans = collector!.drainTrace(traceId, rootSpanId);\n if (spans.length > 0) {\n (task.meta as Record<string, unknown>).otelSpans = spans;\n }\n }\n },\n { auto: true },\n ],\n});\n\nexport { expect, describe, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';\n\n// Re-export all autotel/testing utilities\nexport {\n createTraceCollector,\n assertTraceCreated,\n assertTraceSucceeded,\n assertTraceFailed,\n assertNoErrors,\n assertTraceDuration,\n waitForTrace,\n getTraceDuration,\n createMockLogger,\n type TraceCollector,\n type TestSpan,\n type LogCollector,\n type LogEntry,\n} from 'autotel/testing';\n\n// Re-export trace context helpers for DX convenience\nexport {\n getTraceContext,\n resolveTraceUrl,\n isTracing,\n enrichWithTraceContext,\n} from 'autotel';\n\nexport type { OtelTraceContext } from 'autotel';\n"]}
1
+ {"version":3,"sources":["../src/fixture.ts","../src/index.ts"],"names":["otelContext","base"],"mappings":";;;;;;;;;AAUA,IAAM,WAAA,GAAc,cAAA;AACpB,IAAM,cAAA,GAAiB,OAAA;AAEvB,IAAI,SAAA,GAAsC,IAAA;AAM1C,SAAS,eAAA,GAAqC;AAC5C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,SAAA,GAAY,IAAI,iBAAA,EAAkB;AAClC,IAAA,MAAM,WAAW,wBAAA,EAAyB;AAC1C,IAAA,IAAI,sBAAsB,QAAA,EAAU;AAClC,MAAC,QAAA,CAAyC,gBAAA;AAAA,QACxC,IAAI,oBAAoB,SAAS;AAAA,OACnC;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,SAAA;AACT;AAOO,IAAM,mBAAA,GAAuD;AAAA,EAClE,OACE,EAAE,IAAA,EAAK,EACP,GAAA,KACG;AACH,IAAA,eAAA,EAAgB;AAChB,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,WAAA,EAAa,cAAc,CAAA;AACpD,IAAA,MAAM,OAAO,MAAA,CAAO,SAAA,CAAU,CAAA,KAAA,EAAQ,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI;AAAA,MACjD,UAAA,EAAY;AAAA,QACV,aAAa,IAAA,CAAK,IAAA;AAAA,QAClB,WAAA,EAAa,IAAA,CAAK,IAAA,EAAM,IAAA,IAAQ,EAAA;AAAA,QAChC,YAAA,EAAc,IAAA,CAAK,KAAA,EAAO,IAAA,IAAQ;AAAA;AACpC,KACD,CAAA;AACD,IAAA,MAAM,MAAM,SAAA,CAAU,OAAA,CAAQA,OAAA,CAAY,MAAA,IAAU,IAAI,CAAA;AACxD,IAAA,IAAI;AACF,MAAA,MAAMA,QAAY,IAAA,CAAK,GAAA,EAAK,MAAM,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,IAC7C,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,cAAA,CAAe,OAAO,CAAA;AAC7C,MAAA,IAAA,CAAK,eAAA,CAAgB,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAC9E,MAAA,MAAM,KAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,GAAA,EAAI;AACT,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,WAAA,EAAY,CAAE,OAAA;AACnC,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,WAAA,EAAY,CAAE,MAAA;AACtC,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAW,UAAA,CAAW,OAAA,EAAS,UAAU,CAAA;AACvD,MAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,QAAC,IAAA,CAAK,KAAiC,SAAA,GAAY,KAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAA;AAAA,EACA,EAAE,MAAM,IAAA;AACV,CAAA;AChDO,IAAM,IAAA,GAAOC,OAAK,MAAA,CAAO;AAAA,EAC9B,aAAA,EAAe;AACjB,CAAC","file":"index.js","sourcesContent":["import {\n getTracer,\n getAutotelTracerProvider,\n context as otelContext,\n otelTrace,\n SpanStatusCode,\n} from 'autotel';\nimport { TestSpanCollector } from 'autotel/test-span-collector';\nimport { SimpleSpanProcessor } from 'autotel/processors';\n\nconst TRACER_NAME = 'vitest-tests';\nconst TRACER_VERSION = '0.1.0';\n\nlet collector: TestSpanCollector | null = null;\n\ninterface TracerProviderWithProcessor {\n addSpanProcessor(processor: unknown): void;\n}\n\nfunction ensureCollector(): TestSpanCollector {\n if (!collector) {\n collector = new TestSpanCollector();\n const provider = getAutotelTracerProvider();\n if ('addSpanProcessor' in provider) {\n (provider as TracerProviderWithProcessor).addSpanProcessor(\n new SimpleSpanProcessor(collector),\n );\n }\n }\n return collector;\n}\n\nexport type OtelFixtureFn = (\n args: { task: { name: string; file?: { name: string }; suite?: { name: string }; meta: Record<string, unknown> } },\n use: (span: unknown) => Promise<void>,\n) => Promise<void>;\n\nexport const otelTestSpanFixture: [OtelFixtureFn, { auto: true }] = [\n async (\n { task }: { task: { name: string; file?: { name: string }; suite?: { name: string }; meta: Record<string, unknown> } },\n use: (span: unknown) => Promise<void>,\n ) => {\n ensureCollector();\n const tracer = getTracer(TRACER_NAME, TRACER_VERSION);\n const span = tracer.startSpan(`test:${task.name}`, {\n attributes: {\n 'test.name': task.name,\n 'test.file': task.file?.name ?? '',\n 'test.suite': task.suite?.name ?? '',\n },\n });\n const ctx = otelTrace.setSpan(otelContext.active(), span);\n try {\n await otelContext.with(ctx, () => use(span));\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error instanceof Error ? error : new Error(String(error)));\n throw error;\n } finally {\n span.end();\n const traceId = span.spanContext().traceId;\n const rootSpanId = span.spanContext().spanId;\n const spans = collector!.drainTrace(traceId, rootSpanId);\n if (spans.length > 0) {\n (task.meta as Record<string, unknown>).otelSpans = spans;\n }\n }\n },\n { auto: true },\n];\n","/**\n * autotel-vitest\n *\n * Vitest fixture that creates one OTel span per test so all autotel-instrumented\n * code executed during a test automatically creates child spans under it;\n * making every test run filterable in your OTLP backend.\n *\n * @example\n * // vitest.config.ts: globalSetup calls init({ service: 'unit-tests' })\n * // In spec:\n * import { test, expect } from 'autotel-vitest';\n * test('creates user', async () => {\n * await userService.createUser({ email: 'test@example.com' });\n * // All trace()/span() calls become children of the test span\n * });\n */\n\nimport { test as base } from 'vitest';\nimport { otelTestSpanFixture } from './fixture';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const test = base.extend({\n _otelTestSpan: otelTestSpanFixture as any,\n});\n\nexport { expect, describe, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';\n\n// Re-export all autotel/testing utilities\nexport {\n createTraceCollector,\n assertTraceCreated,\n assertTraceSucceeded,\n assertTraceFailed,\n assertNoErrors,\n assertTraceDuration,\n waitForTrace,\n getTraceDuration,\n createMockLogger,\n type TraceCollector,\n type TestSpan,\n type LogCollector,\n type LogEntry,\n} from 'autotel/testing';\n\n// Re-export trace context helpers for DX convenience\nexport {\n getTraceContext,\n resolveTraceUrl,\n isTracing,\n enrichWithTraceContext,\n} from 'autotel';\n\nexport type { OtelTraceContext } from 'autotel';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel-vitest",
3
- "version": "0.3.5",
3
+ "version": "0.4.0",
4
4
  "description": "Vitest fixture for OpenTelemetry: one span per test so all instrumented code is filterable by test run",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,7 +24,7 @@
24
24
  "README.md"
25
25
  ],
26
26
  "dependencies": {
27
- "autotel": "2.24.1"
27
+ "autotel": "2.25.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "vitest": ">=4.1.0"
@@ -37,7 +37,7 @@
37
37
  "devDependencies": {
38
38
  "tsup": "^8.5.1",
39
39
  "typescript": "^5.9.3",
40
- "vitest": "^4.0.18"
40
+ "vitest": "^4.1.0"
41
41
  },
42
42
  "repository": {
43
43
  "type": "git",
package/src/fixture.ts ADDED
@@ -0,0 +1,70 @@
1
+ import {
2
+ getTracer,
3
+ getAutotelTracerProvider,
4
+ context as otelContext,
5
+ otelTrace,
6
+ SpanStatusCode,
7
+ } from 'autotel';
8
+ import { TestSpanCollector } from 'autotel/test-span-collector';
9
+ import { SimpleSpanProcessor } from 'autotel/processors';
10
+
11
+ const TRACER_NAME = 'vitest-tests';
12
+ const TRACER_VERSION = '0.1.0';
13
+
14
+ let collector: TestSpanCollector | null = null;
15
+
16
+ interface TracerProviderWithProcessor {
17
+ addSpanProcessor(processor: unknown): void;
18
+ }
19
+
20
+ function ensureCollector(): TestSpanCollector {
21
+ if (!collector) {
22
+ collector = new TestSpanCollector();
23
+ const provider = getAutotelTracerProvider();
24
+ if ('addSpanProcessor' in provider) {
25
+ (provider as TracerProviderWithProcessor).addSpanProcessor(
26
+ new SimpleSpanProcessor(collector),
27
+ );
28
+ }
29
+ }
30
+ return collector;
31
+ }
32
+
33
+ export type OtelFixtureFn = (
34
+ args: { task: { name: string; file?: { name: string }; suite?: { name: string }; meta: Record<string, unknown> } },
35
+ use: (span: unknown) => Promise<void>,
36
+ ) => Promise<void>;
37
+
38
+ export const otelTestSpanFixture: [OtelFixtureFn, { auto: true }] = [
39
+ async (
40
+ { task }: { task: { name: string; file?: { name: string }; suite?: { name: string }; meta: Record<string, unknown> } },
41
+ use: (span: unknown) => Promise<void>,
42
+ ) => {
43
+ ensureCollector();
44
+ const tracer = getTracer(TRACER_NAME, TRACER_VERSION);
45
+ const span = tracer.startSpan(`test:${task.name}`, {
46
+ attributes: {
47
+ 'test.name': task.name,
48
+ 'test.file': task.file?.name ?? '',
49
+ 'test.suite': task.suite?.name ?? '',
50
+ },
51
+ });
52
+ const ctx = otelTrace.setSpan(otelContext.active(), span);
53
+ try {
54
+ await otelContext.with(ctx, () => use(span));
55
+ } catch (error) {
56
+ span.setStatus({ code: SpanStatusCode.ERROR });
57
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
58
+ throw error;
59
+ } finally {
60
+ span.end();
61
+ const traceId = span.spanContext().traceId;
62
+ const rootSpanId = span.spanContext().spanId;
63
+ const spans = collector!.drainTrace(traceId, rootSpanId);
64
+ if (spans.length > 0) {
65
+ (task.meta as Record<string, unknown>).otelSpans = spans;
66
+ }
67
+ }
68
+ },
69
+ { auto: true },
70
+ ];
package/src/index.test.ts CHANGED
@@ -1,15 +1,5 @@
1
1
  import { afterEach, describe, expect, it, vi } from 'vitest';
2
2
 
3
- type FixtureFn = (
4
- args: { task: { name: string; file?: { name: string }; suite?: { name: string }; meta: Record<string, unknown> } },
5
- use: (span: unknown) => Promise<void>,
6
- ) => Promise<void>;
7
-
8
- type Fixtures = {
9
- _otelTestSpan?: FixtureFn | [FixtureFn, { auto: true }];
10
- };
11
-
12
- const state: { fixtures?: Fixtures } = {};
13
3
  let spanIdCounter = 0;
14
4
  const createdSpans: Array<{
15
5
  end: ReturnType<typeof vi.fn>;
@@ -18,20 +8,6 @@ const createdSpans: Array<{
18
8
  spanContext: () => { traceId: string; spanId: string };
19
9
  }> = [];
20
10
 
21
- vi.mock('vitest', async () => {
22
- const actual = await vi.importActual<typeof import('vitest')>('vitest');
23
- return {
24
- ...actual,
25
- test: {
26
- ...actual.test,
27
- extend: (fixtures: Fixtures) => {
28
- state.fixtures = fixtures;
29
- return fixtures;
30
- },
31
- },
32
- };
33
- });
34
-
35
11
  vi.mock('autotel', () => ({
36
12
  SpanStatusCode: { UNSET: 0, OK: 1, ERROR: 2 },
37
13
  context: {
@@ -79,21 +55,23 @@ vi.mock('autotel/processors', () => ({
79
55
 
80
56
  describe('autotel-vitest fixture', () => {
81
57
  afterEach(() => {
82
- state.fixtures = undefined;
83
58
  createdSpans.length = 0;
84
59
  spanIdCounter = 0;
85
60
  mockDrainResult = [];
86
61
  vi.resetModules();
87
62
  });
88
63
 
89
- it('creates a span for each test via the _otelTestSpan fixture', async () => {
90
- await import('./index');
64
+ async function getFixture() {
65
+ const { otelTestSpanFixture } = await import('./fixture');
66
+ const [fixtureFn, options] = otelTestSpanFixture;
67
+ return { fixtureFn, options, fixture: otelTestSpanFixture };
68
+ }
91
69
 
92
- const spanFixture = state.fixtures?._otelTestSpan;
93
- const spanFixtureFn = Array.isArray(spanFixture) ? spanFixture[0] : spanFixture;
94
- expect(spanFixtureFn).toBeTypeOf('function');
70
+ it('creates a span for each test via the _otelTestSpan fixture', async () => {
71
+ const { fixtureFn } = await getFixture();
72
+ expect(fixtureFn).toBeTypeOf('function');
95
73
 
96
- await spanFixtureFn?.(
74
+ await fixtureFn(
97
75
  {
98
76
  task: {
99
77
  name: 'creates user',
@@ -110,14 +88,11 @@ describe('autotel-vitest fixture', () => {
110
88
  });
111
89
 
112
90
  it('ends the span after the test completes', async () => {
113
- await import('./index');
114
-
115
- const spanFixture = state.fixtures?._otelTestSpan;
116
- const spanFixtureFn = Array.isArray(spanFixture) ? spanFixture[0] : spanFixture;
91
+ const { fixtureFn } = await getFixture();
117
92
 
118
93
  let spanDuringTest: unknown;
119
94
 
120
- await spanFixtureFn?.(
95
+ await fixtureFn(
121
96
  {
122
97
  task: {
123
98
  name: 'test end timing',
@@ -139,15 +114,12 @@ describe('autotel-vitest fixture', () => {
139
114
  });
140
115
 
141
116
  it('sets error status when the test throws', async () => {
142
- await import('./index');
143
-
144
- const spanFixture = state.fixtures?._otelTestSpan;
145
- const spanFixtureFn = Array.isArray(spanFixture) ? spanFixture[0] : spanFixture;
117
+ const { fixtureFn } = await getFixture();
146
118
 
147
119
  const err = new Error('test failure');
148
120
 
149
121
  await expect(
150
- spanFixtureFn?.(
122
+ fixtureFn(
151
123
  {
152
124
  task: {
153
125
  name: 'failing test',
@@ -173,13 +145,10 @@ describe('autotel-vitest fixture', () => {
173
145
  { spanId: 'span-1', name: 'test:my-test', startTimeMs: 1000, durationMs: 100, status: 'ok' },
174
146
  ];
175
147
 
176
- await import('./index');
177
-
178
- const spanFixture = state.fixtures?._otelTestSpan;
179
- const spanFixtureFn = Array.isArray(spanFixture) ? spanFixture[0] : spanFixture;
148
+ const { fixtureFn } = await getFixture();
180
149
 
181
150
  const meta: Record<string, unknown> = {};
182
- await spanFixtureFn?.(
151
+ await fixtureFn(
183
152
  {
184
153
  task: {
185
154
  name: 'my-test',
@@ -197,12 +166,10 @@ describe('autotel-vitest fixture', () => {
197
166
  });
198
167
 
199
168
  it('uses auto: true to activate for every test', async () => {
200
- await import('./index');
201
-
202
- const spanFixture = state.fixtures?._otelTestSpan;
203
- expect(Array.isArray(spanFixture)).toBe(true);
204
- if (Array.isArray(spanFixture)) {
205
- expect(spanFixture[1]).toEqual({ auto: true });
169
+ const { fixture } = await getFixture();
170
+ expect(Array.isArray(fixture)).toBe(true);
171
+ if (Array.isArray(fixture)) {
172
+ expect(fixture[1]).toEqual({ auto: true });
206
173
  }
207
174
  });
208
175
  });
package/src/index.ts CHANGED
@@ -16,69 +16,11 @@
16
16
  */
17
17
 
18
18
  import { test as base } from 'vitest';
19
- import {
20
- getTracer,
21
- getAutotelTracerProvider,
22
- context as otelContext,
23
- otelTrace,
24
- SpanStatusCode,
25
- } from 'autotel';
26
- import { TestSpanCollector } from 'autotel/test-span-collector';
27
- import { SimpleSpanProcessor } from 'autotel/processors';
28
-
29
- const TRACER_NAME = 'vitest-tests';
30
- const TRACER_VERSION = '0.1.0';
31
-
32
- let collector: TestSpanCollector | null = null;
33
-
34
- interface TracerProviderWithProcessor {
35
- addSpanProcessor(processor: unknown): void;
36
- }
37
-
38
- function ensureCollector(): TestSpanCollector {
39
- if (!collector) {
40
- collector = new TestSpanCollector();
41
- const provider = getAutotelTracerProvider();
42
- if ('addSpanProcessor' in provider) {
43
- (provider as TracerProviderWithProcessor).addSpanProcessor(
44
- new SimpleSpanProcessor(collector),
45
- );
46
- }
47
- }
48
- return collector;
49
- }
19
+ import { otelTestSpanFixture } from './fixture';
50
20
 
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
22
  export const test = base.extend({
52
- _otelTestSpan: [
53
- async ({ task }, use) => {
54
- ensureCollector();
55
- const tracer = getTracer(TRACER_NAME, TRACER_VERSION);
56
- const span = tracer.startSpan(`test:${task.name}`, {
57
- attributes: {
58
- 'test.name': task.name,
59
- 'test.file': task.file?.name ?? '',
60
- 'test.suite': task.suite?.name ?? '',
61
- },
62
- });
63
- const ctx = otelTrace.setSpan(otelContext.active(), span);
64
- try {
65
- await otelContext.with(ctx, () => use(span));
66
- } catch (error) {
67
- span.setStatus({ code: SpanStatusCode.ERROR });
68
- span.recordException(error instanceof Error ? error : new Error(String(error)));
69
- throw error;
70
- } finally {
71
- span.end();
72
- const traceId = span.spanContext().traceId;
73
- const rootSpanId = span.spanContext().spanId;
74
- const spans = collector!.drainTrace(traceId, rootSpanId);
75
- if (spans.length > 0) {
76
- (task.meta as Record<string, unknown>).otelSpans = spans;
77
- }
78
- }
79
- },
80
- { auto: true },
81
- ],
23
+ _otelTestSpan: otelTestSpanFixture as any,
82
24
  });
83
25
 
84
26
  export { expect, describe, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Wiring test: verifies the public `test` export from index.ts
3
+ * actually registers the _otelTestSpan fixture with auto: true.
4
+ *
5
+ * Uses the exported `test` (not vitest's base) to define tests,
6
+ * so if index.ts stops calling base.extend() or drops the fixture,
7
+ * these tests will fail.
8
+ */
9
+ import { expect, vi } from 'vitest';
10
+
11
+ vi.mock('autotel', () => ({
12
+ SpanStatusCode: { UNSET: 0, OK: 1, ERROR: 2 },
13
+ context: {
14
+ active: () => ({}),
15
+ with: (_ctx: unknown, fn: () => Promise<unknown>) => fn(),
16
+ },
17
+ getTracer: () => ({
18
+ startSpan: () => ({
19
+ end: vi.fn(),
20
+ recordException: vi.fn(),
21
+ setStatus: vi.fn(),
22
+ spanContext: () => ({ traceId: 'wiring-trace', spanId: 'wiring-span' }),
23
+ }),
24
+ }),
25
+ otelTrace: {
26
+ setSpan: () => ({}),
27
+ },
28
+ getAutotelTracerProvider: vi.fn(() => ({})),
29
+ getTraceContext: vi.fn(() => null),
30
+ resolveTraceUrl: vi.fn(() => undefined),
31
+ isTracing: vi.fn(() => false),
32
+ enrichWithTraceContext: vi.fn((obj: unknown) => obj),
33
+ }));
34
+
35
+ vi.mock('autotel/test-span-collector', () => ({
36
+ TestSpanCollector: class {
37
+ export = vi.fn();
38
+ drainTrace = vi.fn(() => []);
39
+ shutdown = vi.fn(() => Promise.resolve());
40
+ forceFlush = vi.fn(() => Promise.resolve());
41
+ },
42
+ }));
43
+
44
+ vi.mock('autotel/processors', () => ({
45
+ SimpleSpanProcessor: class {
46
+ constructor() {}
47
+ },
48
+ }));
49
+
50
+ // Import the PUBLIC test — not vitest's base test.
51
+ // If index.ts doesn't wire otelTestSpanFixture via base.extend(),
52
+ // _otelTestSpan won't be available and these tests fail.
53
+ import { test } from './index';
54
+
55
+ test('_otelTestSpan fixture is registered and auto-activates', ({ _otelTestSpan }) => {
56
+ // auto: true means the fixture injects automatically.
57
+ // If the fixture key is missing from base.extend(), this will be undefined.
58
+ expect(_otelTestSpan).toBeDefined();
59
+ });