Skip to content

Commit b6fda2b

Browse files
committed
some tests etc
1 parent 1cf7f7f commit b6fda2b

File tree

11 files changed

+729
-52
lines changed

11 files changed

+729
-52
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# Spotlight Environment Variable E2E Tests
2+
3+
This document describes the E2E tests for Spotlight environment variable handling across different bundlers and module formats.
4+
5+
## Overview
6+
7+
The Sentry JavaScript SDK supports Spotlight configuration via environment variables. The implementation must handle:
8+
9+
1. **Multiple environment variable prefixes** for different frameworks (e.g., `NEXT_PUBLIC_*`, `VITE_*`)
10+
2. **Different module formats** (ESM vs CJS)
11+
3. **Different environment variable access methods** (`process.env` vs `import.meta.env`)
12+
4. **Empty string filtering** (empty strings should be treated as undefined)
13+
14+
## Test Coverage
15+
16+
### Next.js Tests (`nextjs-15/tests/spotlight-env.test.ts`)
17+
18+
Tests the **CJS build** scenario where `import.meta` must be stripped to avoid syntax errors.
19+
20+
**Test Page**: `/spotlight-env-test`
21+
**Source**: `nextjs-15/app/spotlight-env-test/page.tsx`
22+
23+
#### Tests:
24+
1. **`respects NEXT_PUBLIC_SENTRY_SPOTLIGHT environment variable`**
25+
- Verifies that `NEXT_PUBLIC_SENTRY_SPOTLIGHT=true` enables Spotlight
26+
- Checks that the Spotlight integration is registered
27+
28+
2. **`NEXT_PUBLIC_SENTRY_SPOTLIGHT takes precedence over SENTRY_SPOTLIGHT`**
29+
- Verifies that `SENTRY_SPOTLIGHT` (backend-only) is not accessible in browser
30+
- Ensures framework-specific vars have priority
31+
32+
3. **`handles empty string environment variables correctly`**
33+
- Documents expected behavior: empty strings should disable Spotlight
34+
- Tests that `resolveSpotlightOptions` filters empty strings
35+
36+
4. **`process.env check works without errors in CJS build`**
37+
- **Critical test**: Verifies no `import.meta` syntax errors in CJS build
38+
- Checks that the rollup plugin successfully stripped ESM-only code
39+
- Monitors console for syntax errors
40+
41+
#### Environment Setup:
42+
```bash
43+
NEXT_PUBLIC_SENTRY_SPOTLIGHT=true
44+
# SENTRY_SPOTLIGHT can be set for backend, but won't be exposed to browser
45+
```
46+
47+
### Vite Tests (`browser-webworker-vite/tests/spotlight-env.test.ts`)
48+
49+
Tests the **ESM build** scenario where `import.meta` should be present and functional.
50+
51+
**Test Page**: `/spotlight-env-test.html`
52+
**Source**: `browser-webworker-vite/src/spotlight-env-test.ts`
53+
54+
#### Tests:
55+
1. **`respects VITE_SENTRY_SPOTLIGHT environment variable`**
56+
- Verifies that `VITE_SENTRY_SPOTLIGHT=true` enables Spotlight
57+
- Checks that the Spotlight integration is registered
58+
59+
2. **`import.meta.env is available in ESM build`**
60+
- **Critical test**: Verifies `import.meta` is present in ESM builds
61+
- Checks that `import.meta.env.VITE_SENTRY_SPOTLIGHT` is accessible
62+
- Confirms the build format is ESM
63+
64+
3. **`process.env also works via Vite transformation`**
65+
- Verifies that Vite transforms `process.env` references
66+
- Both `process.env` and `import.meta.env` should work
67+
68+
4. **`handles empty string environment variables correctly`**
69+
- Documents expected behavior for empty strings
70+
- Tests that `resolveSpotlightOptions` filters empty strings
71+
72+
5. **`no syntax errors from import.meta in ESM build`**
73+
- Verifies no syntax errors when using `import.meta`
74+
- Monitors console for errors
75+
76+
6. **`getEnvValue function works with import.meta.env`**
77+
- Tests the `getEnvValue` utility function
78+
- Verifies it successfully reads from `import.meta.env`
79+
80+
#### Environment Setup:
81+
```bash
82+
VITE_SENTRY_SPOTLIGHT=true
83+
```
84+
85+
## Implementation Details
86+
87+
### Rollup Plugins
88+
89+
Two rollup plugins handle module-format-specific code:
90+
91+
1. **`makeStripEsmPlugin()`** - Strips ESM-only code from CJS builds
92+
- Removes code between `/* rollup-esm-only */` and `/* rollup-esm-only-end */`
93+
- Applied to all CJS builds
94+
95+
2. **`makeStripCjsPlugin()`** - Strips CJS-only code from ESM builds
96+
- Removes code between `/* rollup-cjs-only */` and `/* rollup-cjs-only-end */`
97+
- Applied to all ESM builds
98+
99+
### Source Code
100+
101+
**File**: `packages/browser/src/utils/env.ts`
102+
103+
The `import.meta.env` check is wrapped in special comments:
104+
105+
```typescript
106+
/* rollup-esm-only */
107+
// Check import.meta.env (Vite, Astro, SvelteKit, etc.)
108+
try {
109+
if (typeof import.meta !== 'undefined' && import.meta.env) {
110+
const value = import.meta.env[key];
111+
if (value !== undefined) {
112+
return value;
113+
}
114+
}
115+
} catch (e) {
116+
// Silently ignore
117+
}
118+
/* rollup-esm-only-end */
119+
```
120+
121+
This code is:
122+
- **Included** in ESM builds (Vite, Astro, SvelteKit)
123+
- **Stripped** from CJS builds (Next.js, Webpack, etc.)
124+
125+
### Empty String Handling
126+
127+
**File**: `packages/core/src/utils/resolveSpotlightOptions.ts`
128+
129+
The shared `resolveSpotlightOptions` function filters empty/whitespace strings:
130+
131+
```typescript
132+
// Treat empty/whitespace-only strings as undefined
133+
const envUrl = typeof envSpotlight === 'string' && envSpotlight.trim() !== ''
134+
? envSpotlight
135+
: undefined;
136+
```
137+
138+
This ensures:
139+
- Empty strings never enable Spotlight
140+
- Whitespace-only strings are treated as undefined
141+
- No invalid URL connections are attempted
142+
143+
## Running the Tests
144+
145+
### Next.js Tests
146+
```bash
147+
cd dev-packages/e2e-tests/test-applications/nextjs-15
148+
NEXT_PUBLIC_SENTRY_SPOTLIGHT=true pnpm test tests/spotlight-env.test.ts
149+
```
150+
151+
### Vite Tests
152+
```bash
153+
cd dev-packages/e2e-tests/test-applications/browser-webworker-vite
154+
VITE_SENTRY_SPOTLIGHT=true pnpm test tests/spotlight-env.test.ts
155+
```
156+
157+
## Expected Outcomes
158+
159+
### Next.js (CJS)
160+
-`process.env.NEXT_PUBLIC_SENTRY_SPOTLIGHT` accessible
161+
-`SENTRY_SPOTLIGHT` NOT accessible (backend-only)
162+
- ✅ No `import.meta` syntax in output
163+
- ✅ No syntax errors
164+
- ✅ Spotlight integration enabled
165+
166+
### Vite (ESM)
167+
-`import.meta.env.VITE_SENTRY_SPOTLIGHT` accessible
168+
-`process.env.VITE_SENTRY_SPOTLIGHT` accessible (transformed)
169+
-`import.meta` syntax present in output
170+
- ✅ No syntax errors
171+
- ✅ Spotlight integration enabled
172+
173+
## Troubleshooting
174+
175+
### Syntax Error: Cannot use import.meta outside a module
176+
- **Cause**: `import.meta` code not stripped from CJS build
177+
- **Fix**: Verify `makeStripEsmPlugin()` is applied to CJS builds
178+
- **Check**: Look for `/* rollup-esm-only */` comments in source
179+
180+
### Spotlight not enabled despite env var set
181+
- **Cause**: Empty string or wrong prefix
182+
- **Fix**: Use correct prefix (`NEXT_PUBLIC_*` for Next.js, `VITE_*` for Vite)
183+
- **Check**: Verify `resolveSpotlightOptions` receives non-empty string
184+
185+
### import.meta.env returns undefined in Vite
186+
- **Cause**: `import.meta` code stripped from ESM build
187+
- **Fix**: Verify `makeStripEsmPlugin()` is NOT applied to ESM builds
188+
- **Check**: ESM builds should only use `makeStripCjsPlugin()`
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Spotlight Env Test - Vite</title>
7+
</head>
8+
<body>
9+
<h1>Spotlight Environment Variable Test (Vite)</h1>
10+
11+
<div id="env-vars" data-testid="env-vars">
12+
<h2>Environment Variables</h2>
13+
<div data-testid="vite-spotlight">
14+
VITE_SENTRY_SPOTLIGHT: <span id="vite-spotlight-value">Loading...</span>
15+
</div>
16+
<div data-testid="process-env-spotlight">
17+
process.env.SENTRY_SPOTLIGHT: <span id="process-env-value">Loading...</span>
18+
</div>
19+
<div data-testid="import-meta-env-spotlight">
20+
import.meta.env.VITE_SENTRY_SPOTLIGHT: <span id="import-meta-value">Loading...</span>
21+
</div>
22+
</div>
23+
24+
<div id="spotlight-status" data-testid="spotlight-status">
25+
<h2>Spotlight Integration Status</h2>
26+
<div data-testid="spotlight-integration-found">
27+
Spotlight Integration: <span id="spotlight-status-value">Loading...</span>
28+
</div>
29+
</div>
30+
31+
<div id="build-format" data-testid="build-format">
32+
<h2>Build Format Check</h2>
33+
<div data-testid="import-meta-available">
34+
import.meta available: <span id="import-meta-available-value">Loading...</span>
35+
</div>
36+
</div>
37+
38+
<script type="module" src="/src/spotlight-env-test.ts"></script>
39+
</body>
40+
</html>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
Sentry.init({
4+
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
5+
debug: true,
6+
tunnel: 'http://localhost:3031/',
7+
tracesSampleRate: 1.0,
8+
});
9+
10+
// Check environment variables
11+
let viteSpotlight = 'undefined';
12+
let processEnvSpotlight = 'undefined';
13+
let importMetaSpotlight = 'undefined';
14+
15+
try {
16+
// Check process.env (should work via bundler transformation)
17+
if (typeof process !== 'undefined' && process.env) {
18+
// @ts-expect-error - accessing process.env for testing
19+
processEnvSpotlight = process.env.VITE_SENTRY_SPOTLIGHT || 'undefined';
20+
}
21+
} catch (e) {
22+
processEnvSpotlight = 'error: ' + (e as Error).message;
23+
}
24+
25+
try {
26+
// Check import.meta.env (Vite-specific)
27+
if (typeof import.meta !== 'undefined' && import.meta.env) {
28+
importMetaSpotlight = import.meta.env.VITE_SENTRY_SPOTLIGHT || 'undefined';
29+
viteSpotlight = importMetaSpotlight;
30+
}
31+
} catch (e) {
32+
importMetaSpotlight = 'error: ' + (e as Error).message;
33+
}
34+
35+
// Check if Spotlight integration is registered
36+
const client = Sentry.getClient();
37+
const spotlightIntegration = client?.getIntegrationByName?.('SpotlightBrowser');
38+
const spotlightEnabled = !!spotlightIntegration;
39+
40+
// Check if import.meta is available (ESM build check)
41+
let importMetaAvailable = false;
42+
try {
43+
importMetaAvailable = typeof import.meta !== 'undefined';
44+
} catch (e) {
45+
importMetaAvailable = false;
46+
}
47+
48+
// Update DOM
49+
document.getElementById('vite-spotlight-value')!.textContent = viteSpotlight;
50+
document.getElementById('process-env-value')!.textContent = processEnvSpotlight;
51+
document.getElementById('import-meta-value')!.textContent = importMetaSpotlight;
52+
document.getElementById('spotlight-status-value')!.textContent = spotlightEnabled ? 'ENABLED' : 'DISABLED';
53+
document.getElementById('import-meta-available-value')!.textContent = importMetaAvailable ? 'YES (ESM)' : 'NO (CJS)';
54+
55+
console.log('Spotlight env test results:', {
56+
viteSpotlight,
57+
processEnvSpotlight,
58+
importMetaSpotlight,
59+
spotlightEnabled,
60+
importMetaAvailable,
61+
});

0 commit comments

Comments
 (0)