autotel-vitest 0.4.30 → 0.4.32

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel-vitest",
3
- "version": "0.4.30",
3
+ "version": "0.4.32",
4
4
  "description": "Vitest fixture for OpenTelemetry: one span per test so all instrumented code is filterable by test run",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,10 +22,11 @@
22
22
  "files": [
23
23
  "dist",
24
24
  "src",
25
- "README.md"
25
+ "README.md",
26
+ "skills"
26
27
  ],
27
28
  "dependencies": {
28
- "autotel": "3.7.0"
29
+ "autotel": "4.0.0"
29
30
  },
30
31
  "peerDependencies": {
31
32
  "vitest": ">=4.1.8"
@@ -0,0 +1,207 @@
1
+ ---
2
+ name: autotel-vitest
3
+ description: >
4
+ Use this skill when adding OpenTelemetry tracing to Vitest tests — gives each test a parent span so all instrumented code becomes filterable child spans in your OTLP backend.
5
+ ---
6
+
7
+ # autotel-vitest
8
+
9
+ Vitest fixture that creates one OTel span per test so all `autotel`-instrumented code executed during a test automatically runs as child spans. Makes every test run filterable by trace ID in your OTLP backend (Jaeger, Honeycomb, Datadog, etc.).
10
+
11
+ ## Setup
12
+
13
+ ### 1. Install
14
+
15
+ ```bash
16
+ pnpm add autotel autotel-vitest
17
+ pnpm add -D vitest
18
+ ```
19
+
20
+ ### 2. globalSetup.ts — call init() before tests run
21
+
22
+ ```typescript
23
+ // globalSetup.ts
24
+ import { init } from 'autotel';
25
+
26
+ export default function globalSetup() {
27
+ init({
28
+ service: 'unit-tests',
29
+ endpoint: 'http://localhost:4318', // Your OTLP collector
30
+ });
31
+ }
32
+ ```
33
+
34
+ ### 3. vitest.config.ts — register globalSetup
35
+
36
+ ```typescript
37
+ // vitest.config.ts
38
+ import { defineConfig } from 'vitest/config';
39
+
40
+ export default defineConfig({
41
+ test: {
42
+ globalSetup: './globalSetup.ts',
43
+ },
44
+ });
45
+ ```
46
+
47
+ ### 4. Import test from autotel-vitest
48
+
49
+ ```typescript
50
+ import { test, expect } from 'autotel-vitest';
51
+
52
+ test('creates user', async () => {
53
+ await userService.createUser({ email: 'test@example.com' });
54
+ // All trace()/span() calls in userService become child spans of this test
55
+ expect(true).toBe(true);
56
+ });
57
+ ```
58
+
59
+ The fixture is `auto: true` — every test gets a parent span automatically with no extra code.
60
+
61
+ ## Configuration / Core Patterns
62
+
63
+ ### Per-test span attributes
64
+
65
+ Each test span is named `test:${task.name}` and carries these attributes automatically:
66
+
67
+ - `test.name` — the test name string
68
+ - `test.file` — file path from `task.file.name`
69
+ - `test.suite` — suite name from `task.suite.name` (if in a describe block)
70
+
71
+ If a test throws, the span is marked `ERROR` and records the exception.
72
+
73
+ ### Optional: OtelReporter (runner-process spans)
74
+
75
+ The fixture creates spans in the **worker** process. If you also want **runner-process** spans for test/suite timing (visible in your OTLP backend as a hierarchy), add the reporter:
76
+
77
+ ```typescript
78
+ // vitest.config.ts
79
+ import { defineConfig } from 'vitest/config';
80
+
81
+ export default defineConfig({
82
+ test: {
83
+ globalSetup: './globalSetup.ts',
84
+ reporters: ['default', 'autotel-vitest/reporter'],
85
+ },
86
+ });
87
+ ```
88
+
89
+ Reporter creates:
90
+ - `test:<name>` spans for each test case
91
+ - `suite:<name>` spans for each describe block
92
+
93
+ ### Testing utilities (re-exported from autotel/testing)
94
+
95
+ ```typescript
96
+ import {
97
+ test,
98
+ createTraceCollector,
99
+ assertTraceCreated,
100
+ assertTraceSucceeded,
101
+ assertTraceFailed,
102
+ assertNoErrors,
103
+ assertTraceDuration,
104
+ waitForTrace,
105
+ getTraceDuration,
106
+ createMockLogger,
107
+ } from 'autotel-vitest';
108
+
109
+ test('traces user creation', async () => {
110
+ const collector = createTraceCollector();
111
+ await userService.createUser({ email: 'test@example.com' });
112
+ assertTraceCreated(collector, 'user.createUser');
113
+ assertTraceSucceeded(collector, 'user.createUser');
114
+ });
115
+ ```
116
+
117
+ ### Trace context helpers (re-exported from autotel)
118
+
119
+ ```typescript
120
+ import { getTraceContext, resolveTraceUrl, isTracing, enrichWithTraceContext } from 'autotel-vitest';
121
+ ```
122
+
123
+ ### Cross-process tracing (test → HTTP server)
124
+
125
+ When the server runs in a separate process, inject the trace context into the HTTP request so both sides share the same trace ID:
126
+
127
+ ```typescript
128
+ import { test } from 'autotel-vitest';
129
+ import { injectTraceContext, extractTraceContext } from 'autotel/http';
130
+
131
+ test('traces across HTTP', async () => {
132
+ const response = await fetch('http://localhost:3000/api/users', {
133
+ headers: injectTraceContext(), // adds traceparent header
134
+ });
135
+ // Server must call extractTraceContext(req.headers) and run in that context
136
+ // Both test span and server spans appear under the same trace ID in OTLP
137
+ });
138
+ ```
139
+
140
+ ## Common Mistakes
141
+
142
+ ### HIGH — Importing test from vitest instead of autotel-vitest
143
+
144
+ Wrong:
145
+ ```typescript
146
+ import { test } from 'vitest'; // base test — no OTel fixture
147
+
148
+ test('creates user', async () => {
149
+ await userService.createUser({ email: 'test@example.com' });
150
+ // No parent span — instrumented code spans are unlinked orphans
151
+ });
152
+ ```
153
+
154
+ Correct:
155
+ ```typescript
156
+ import { test } from 'autotel-vitest'; // extended test with auto fixture
157
+ ```
158
+
159
+ Explanation: Only the extended `test` from `autotel-vitest` has the `_otelTestSpan` fixture registered. Using the base `vitest` `test` means no parent context is active and child spans appear as disconnected traces.
160
+
161
+ ### HIGH — Not calling init() in globalSetup
162
+
163
+ Wrong:
164
+ ```typescript
165
+ // vitest.config.ts — no globalSetup
166
+ // Spans are created but never exported (no tracer provider configured)
167
+ ```
168
+
169
+ Correct:
170
+ ```typescript
171
+ // globalSetup.ts
172
+ import { init } from 'autotel';
173
+ export default function globalSetup() {
174
+ init({ service: 'unit-tests', endpoint: 'http://localhost:4318' });
175
+ }
176
+ ```
177
+
178
+ Explanation: `init()` must run in `globalSetup` (not in a `beforeAll` or test file) so the provider is available before any worker process starts executing tests.
179
+
180
+ ### MEDIUM — Adding the reporter without globalSetup
181
+
182
+ Wrong:
183
+ ```typescript
184
+ // vitest.config.ts
185
+ export default defineConfig({
186
+ test: {
187
+ reporters: ['default', 'autotel-vitest/reporter'],
188
+ // No globalSetup — init() never called in the runner process
189
+ },
190
+ });
191
+ ```
192
+
193
+ Correct: Always pair the reporter with `globalSetup` that calls `init()`.
194
+
195
+ Explanation: The reporter runs in the Vitest runner process and calls `getTracer()`. If `init()` was never called, there is no configured tracer provider and spans silently go nowhere.
196
+
197
+ ### MEDIUM — Calling describe/beforeEach from vitest directly when using autotel-vitest
198
+
199
+ These are safe to mix — `autotel-vitest` re-exports `describe`, `beforeEach`, `afterEach`, `beforeAll`, `afterAll` directly from `vitest`, so you can import everything from one place:
200
+
201
+ ```typescript
202
+ import { test, expect, describe, beforeEach } from 'autotel-vitest';
203
+ ```
204
+
205
+ ## Version
206
+
207
+ Targets autotel-vitest v0.4.4. Requires `vitest >=4.1.0` (peer), `autotel` (peer). The fixture uses `auto: true` (Vitest 4+ fixture API).