|
| 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()` |
0 commit comments