rollbar 2.26.4 → 3.0.0-alpha.2

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.
Files changed (140) hide show
  1. package/.claude/settings.local.json +3 -0
  2. package/.cursor/rules/guidelines.mdc +154 -0
  3. package/.github/workflows/ci.yml +4 -6
  4. package/CLAUDE.local.md +297 -0
  5. package/CLAUDE.md +201 -0
  6. package/CLAUDE.testrunner.md +470 -0
  7. package/Gruntfile.js +59 -16
  8. package/Makefile +3 -3
  9. package/SECURITY.md +5 -0
  10. package/babel.config.json +9 -0
  11. package/codex.md +148 -0
  12. package/dist/plugins/jquery.min.js +1 -1
  13. package/dist/rollbar.js +19332 -6596
  14. package/dist/rollbar.js.map +1 -1
  15. package/dist/rollbar.min.js +2 -1
  16. package/dist/rollbar.min.js.LICENSE.txt +1 -0
  17. package/dist/rollbar.min.js.map +1 -1
  18. package/dist/rollbar.named-amd.js +19332 -6596
  19. package/dist/rollbar.named-amd.js.map +1 -1
  20. package/dist/rollbar.named-amd.min.js +2 -1
  21. package/dist/rollbar.named-amd.min.js.LICENSE.txt +1 -0
  22. package/dist/rollbar.named-amd.min.js.map +1 -1
  23. package/dist/rollbar.noconflict.umd.js +19319 -6581
  24. package/dist/rollbar.noconflict.umd.js.map +1 -1
  25. package/dist/rollbar.noconflict.umd.min.js +2 -1
  26. package/dist/rollbar.noconflict.umd.min.js.LICENSE.txt +1 -0
  27. package/dist/rollbar.noconflict.umd.min.js.map +1 -1
  28. package/dist/rollbar.snippet.js +1 -1
  29. package/dist/rollbar.umd.js +19333 -6597
  30. package/dist/rollbar.umd.js.map +1 -1
  31. package/dist/rollbar.umd.min.js +2 -1
  32. package/dist/rollbar.umd.min.js.LICENSE.txt +1 -0
  33. package/dist/rollbar.umd.min.js.map +1 -1
  34. package/eslint.config.mjs +33 -0
  35. package/karma.conf.js +5 -14
  36. package/package.json +19 -20
  37. package/src/api.js +57 -4
  38. package/src/apiUtility.js +2 -3
  39. package/src/browser/core.js +37 -9
  40. package/src/browser/replay/defaults.js +70 -0
  41. package/src/browser/replay/recorder.js +194 -0
  42. package/src/browser/replay/replayMap.js +195 -0
  43. package/src/browser/rollbar.js +11 -7
  44. package/src/browser/telemetry.js +3 -3
  45. package/src/browser/transport/fetch.js +17 -4
  46. package/src/browser/transport/xhr.js +17 -1
  47. package/src/browser/transport.js +11 -8
  48. package/src/defaults.js +1 -1
  49. package/src/queue.js +65 -4
  50. package/src/react-native/rollbar.js +1 -1
  51. package/src/rollbar.js +52 -10
  52. package/src/server/rollbar.js +3 -2
  53. package/src/telemetry.js +76 -11
  54. package/src/tracing/context.js +24 -0
  55. package/src/tracing/contextManager.js +37 -0
  56. package/src/tracing/defaults.js +7 -0
  57. package/src/tracing/exporter.js +188 -0
  58. package/src/tracing/hrtime.js +98 -0
  59. package/src/tracing/id.js +24 -0
  60. package/src/tracing/session.js +55 -0
  61. package/src/tracing/span.js +92 -0
  62. package/src/tracing/spanProcessor.js +15 -0
  63. package/src/tracing/tracer.js +46 -0
  64. package/src/tracing/tracing.js +89 -0
  65. package/src/utility.js +34 -0
  66. package/test/api.test.js +57 -12
  67. package/test/apiUtility.test.js +5 -6
  68. package/test/browser.core.test.js +1 -10
  69. package/test/browser.domUtility.test.js +1 -1
  70. package/test/browser.predicates.test.js +1 -1
  71. package/test/browser.replay.recorder.test.js +430 -0
  72. package/test/browser.rollbar.test.js +58 -12
  73. package/test/browser.telemetry.test.js +1 -1
  74. package/test/browser.transforms.test.js +20 -13
  75. package/test/browser.transport.test.js +5 -4
  76. package/test/browser.url.test.js +1 -1
  77. package/test/fixtures/replay/index.js +20 -0
  78. package/test/fixtures/replay/payloads.fixtures.js +229 -0
  79. package/test/fixtures/replay/rrwebEvents.fixtures.js +251 -0
  80. package/test/fixtures/replay/rrwebSyntheticEvents.fixtures.js +328 -0
  81. package/test/notifier.test.js +1 -1
  82. package/test/predicates.test.js +1 -1
  83. package/test/queue.test.js +1 -1
  84. package/test/rateLimiter.test.js +1 -1
  85. package/test/react-native.rollbar.test.js +1 -1
  86. package/test/react-native.transforms.test.js +2 -2
  87. package/test/react-native.transport.test.js +3 -3
  88. package/test/replay/index.js +2 -0
  89. package/test/replay/integration/api.spans.test.js +136 -0
  90. package/test/replay/integration/e2e.test.js +228 -0
  91. package/test/replay/integration/index.js +9 -0
  92. package/test/replay/integration/queue.replayMap.test.js +332 -0
  93. package/test/replay/integration/replayMap.test.js +163 -0
  94. package/test/replay/integration/sessionRecording.test.js +390 -0
  95. package/test/replay/unit/api.postSpans.test.js +150 -0
  96. package/test/replay/unit/index.js +7 -0
  97. package/test/replay/unit/queue.replayMap.test.js +225 -0
  98. package/test/replay/unit/replayMap.test.js +348 -0
  99. package/test/replay/util/index.js +5 -0
  100. package/test/replay/util/mockRecordFn.js +80 -0
  101. package/test/server.lambda.mocha.test.mjs +172 -0
  102. package/test/server.locals.constructor.mocha.test.mjs +80 -0
  103. package/test/server.locals.error-handling.mocha.test.mjs +387 -0
  104. package/test/server.locals.merge.mocha.test.mjs +267 -0
  105. package/test/server.locals.test-utils.mjs +114 -0
  106. package/test/server.parser.mocha.test.mjs +87 -0
  107. package/test/server.predicates.mocha.test.mjs +63 -0
  108. package/test/server.rollbar.constructor.mocha.test.mjs +199 -0
  109. package/test/server.rollbar.handlers.mocha.test.mjs +253 -0
  110. package/test/server.rollbar.logging.mocha.test.mjs +326 -0
  111. package/test/server.rollbar.misc.mocha.test.mjs +44 -0
  112. package/test/server.rollbar.test-utils.mjs +57 -0
  113. package/test/server.telemetry.mocha.test.mjs +377 -0
  114. package/test/server.transforms.data.mocha.test.mjs +163 -0
  115. package/test/server.transforms.error.mocha.test.mjs +199 -0
  116. package/test/server.transforms.request.mocha.test.mjs +208 -0
  117. package/test/server.transforms.scrub.mocha.test.mjs +140 -0
  118. package/test/server.transforms.sourcemaps.mocha.test.mjs +122 -0
  119. package/test/server.transforms.test-utils.mjs +62 -0
  120. package/test/server.transport.mocha.test.mjs +269 -0
  121. package/test/telemetry.test.js +132 -1
  122. package/test/tracing/contextManager.test.js +28 -0
  123. package/test/tracing/exporter.toPayload.test.js +400 -0
  124. package/test/tracing/id.test.js +24 -0
  125. package/test/tracing/span.test.js +183 -0
  126. package/test/tracing/spanProcessor.test.js +73 -0
  127. package/test/tracing/tracing.test.js +105 -0
  128. package/test/transforms.test.js +2 -2
  129. package/test/truncation.test.js +2 -2
  130. package/test/utility.test.js +44 -6
  131. package/webpack.config.js +6 -44
  132. package/.eslintignore +0 -7
  133. package/test/server.lambda.test.js +0 -194
  134. package/test/server.locals.test.js +0 -1068
  135. package/test/server.parser.test.js +0 -78
  136. package/test/server.predicates.test.js +0 -91
  137. package/test/server.rollbar.test.js +0 -728
  138. package/test/server.telemetry.test.js +0 -443
  139. package/test/server.transforms.test.js +0 -1193
  140. package/test/server.transport.test.js +0 -269
@@ -0,0 +1,470 @@
1
+ # Test Runner Migration: Karma → Web Test Runner
2
+
3
+ ## Table of Contents
4
+ 1. [Overview](#overview)
5
+ 2. [Understanding JavaScript Testing Environments](#understanding-javascript-testing-environments)
6
+ 3. [Current State Analysis](#current-state-analysis)
7
+ 4. [Migration Strategy](#migration-strategy)
8
+ 5. [Implementation Plan](#implementation-plan)
9
+ 6. [Technical Details](#technical-details)
10
+ 7. [Success Metrics](#success-metrics)
11
+ 8. [Rollback Plan](#rollback-plan)
12
+
13
+ ## Overview
14
+
15
+ This document outlines the migration from the deprecated Karma test runner to the modern Web Test Runner (@web/test-runner) for the Rollbar.js SDK. This migration is part of the broader modernization effort to enable TypeScript support and improve developer experience.
16
+
17
+ ### Goals
18
+ - Replace deprecated Karma with actively maintained Web Test Runner
19
+ - **Eliminate Grunt dependency** - run tests directly via npm scripts
20
+ - Improve test execution speed by 50-70%
21
+ - Enable native TypeScript support for future migration
22
+ - Simplify test configuration and maintenance
23
+ - Maintain 100% test compatibility
24
+
25
+ ### Approach
26
+ - **Strategy**: Incremental migration with parallel validation
27
+ - **Risk Level**: Low (keeping existing setup as fallback)
28
+
29
+ ## Understanding JavaScript Testing Environments
30
+
31
+ ### The Two Worlds of JavaScript
32
+
33
+ JavaScript runs in two fundamentally different environments, and understanding this distinction is crucial for our testing strategy:
34
+
35
+ #### 1. Browser Environment
36
+ - **What it has**: DOM, window object, document, localStorage, fetch API
37
+ - **What it lacks**: Filesystem access, process control, native modules
38
+ - **Security**: Sandboxed for safety (can't read your hard drive!)
39
+ - **Examples**: Chrome, Firefox, Safari, Edge
40
+
41
+ #### 2. Node.js Environment
42
+ - **What it has**: Filesystem (`fs`), process object, Buffer, native modules
43
+ - **What it lacks**: DOM, window, browser-specific APIs
44
+ - **Security**: Full system access (can read/write files)
45
+ - **Examples**: Your terminal, web servers, build tools
46
+
47
+ ### Why This Matters for Rollbar.js
48
+
49
+ The Rollbar SDK must work in BOTH environments:
50
+
51
+ ```javascript
52
+ // Browser usage
53
+ <script src="rollbar.min.js"></script>
54
+ <script>
55
+ Rollbar.init({ accessToken: 'abc123' });
56
+ </script>
57
+
58
+ // Node.js usage
59
+ import Rollbar from 'rollbar';
60
+ const rollbar = new Rollbar({ accessToken: 'abc123' });
61
+ ```
62
+
63
+ This dual-environment requirement means we need different test strategies:
64
+ - **Browser tests**: Need a real browser to test DOM manipulation, window.onerror, etc.
65
+ - **Server tests**: Need Node.js to test filesystem operations, process handling, etc.
66
+
67
+ ### Test Framework vs Test Runner
68
+
69
+ **Test Framework (Mocha)**
70
+ - Provides the structure for writing tests
71
+ - Defines `describe()`, `it()`, `beforeEach()`, etc.
72
+ - Framework-agnostic (works in any JavaScript environment)
73
+
74
+ ```javascript
75
+ describe('Calculator', () => {
76
+ it('should add numbers', () => {
77
+ expect(1 + 1).to.equal(2);
78
+ });
79
+ });
80
+ ```
81
+
82
+ **Test Runner**
83
+ - Executes the tests in the appropriate environment
84
+ - For browsers: Launches browser, serves files, collects results
85
+ - For Node.js: Just runs the JavaScript file directly
86
+
87
+ ### Our Testing Architecture
88
+
89
+ ```
90
+ ┌─────────────────────────────────────────────────────────────┐
91
+ │ Rollbar.js Tests │
92
+ ├─────────────────────────────┬───────────────────────────────┤
93
+ │ Browser Tests (~478) │ Server Tests (~126) │
94
+ ├─────────────────────────────┼───────────────────────────────┤
95
+ │ Environment: Browser │ Environment: Node.js │
96
+ │ Runner: Web Test Runner │ Runner: Node.js (direct) │
97
+ │ Browser: Playwright │ Browser: N/A │
98
+ │ Framework: Mocha │ Framework: Mocha │
99
+ │ Assertions: Chai/Expect │ Assertions: Chai │
100
+ └─────────────────────────────┴───────────────────────────────┘
101
+ ```
102
+
103
+ ## Current State Analysis
104
+
105
+ ### Test Infrastructure Metrics
106
+ - **Total Tests**: ~604 (478 browser + 126 server)
107
+ - **Test Runner**: Karma 6.4.4 (deprecated, last update 2023)
108
+ - **Execution Time**: ~27 seconds (23s browser + 4s server)
109
+ - **Configuration Complexity**: 91 lines Karma + 273 lines Grunt
110
+
111
+ ### Current Grunt Dependency
112
+ The tests currently run through Grunt tasks:
113
+ - `grunt test` → runs `grunt test-browser`
114
+ - `grunt test-browser` → orchestrates multiple Karma runs
115
+ - `grunt test-replay` → runs replay-specific tests
116
+ - `grunt karma:api`, `grunt karma:browser.core`, etc.
117
+
118
+ **We will eliminate this entire layer**, running Web Test Runner directly via npm scripts.
119
+
120
+ ### Current Pain Points
121
+
122
+ 1. **Maintenance Burden**
123
+ - Karma is deprecated with security vulnerabilities
124
+ - Complex configuration spread across multiple files
125
+ - Difficult debugging experience
126
+
127
+ 2. **Developer Experience**
128
+ - Poor error messages from Karma
129
+ - No stack traces on test failures (obfuscated/minified code)
130
+ - No way to manually test directly in browsers
131
+ - No native ES module support
132
+ - Complex watch mode setup
133
+
134
+ 3. **Performance Issues**
135
+ - Sequential test suite execution
136
+ - Webpack rebundling for each suite (500ms overhead × 13 suites)
137
+ - Bundle sizes up to 4.82MB for single test suites
138
+
139
+ ### Test Categories and Distribution
140
+
141
+ | Category | Test Count | Current Runner | Bundle Size |
142
+ | -------------- | ---------- | -------------- | ----------- |
143
+ | API | 5 | Karma | 691 KB |
144
+ | API Utility | 14 | Karma | 425 KB |
145
+ | Browser Core | 16 | Karma | 2.31 MB |
146
+ | DOM Utility | 15 | Karma | 73.4 KB |
147
+ | Predicates | 4 | Karma | 369 KB |
148
+ | Replay Tests | 50 | Karma | 2.43 MB |
149
+ | Browser Tests | 67 | Karma | 4.82 MB |
150
+ | Transforms | 42 | Karma | 1.74 MB |
151
+ | Utility | 37 | Karma | 395 KB |
152
+ | Tracing | 28 | Karma | 444 KB |
153
+ | Examples | 163 | Karma | Various |
154
+ | Server Tests | 126 | Mocha | N/A |
155
+
156
+ ## Migration Strategy
157
+
158
+ ### Architectural Decision: Two Test Runners
159
+
160
+ After careful consideration, we'll maintain two separate test runners:
161
+
162
+ 1. **Web Test Runner** for browser tests (using **Playwright** for browser automation)
163
+ 2. **Direct Mocha execution** for server tests
164
+
165
+ **Rationale:**
166
+ - Clear separation of concerns
167
+ - Optimal performance for each environment
168
+ - Simpler debugging and maintenance
169
+ - Aligns with JavaScript ecosystem best practices
170
+
171
+ **Browser Automation: Playwright**
172
+ We're using Playwright as our browser launcher because:
173
+ - Cross-browser support (Chromium, Firefox, WebKit/Safari)
174
+ - Actively maintained by Microsoft
175
+ - Better performance than legacy WebDriver solutions
176
+ - Native support in Web Test Runner
177
+ - Future-proof for advanced testing scenarios
178
+
179
+ ### Phased Approach
180
+
181
+ We'll migrate in 5 phases to minimize risk and ensure thorough validation:
182
+
183
+ #### Phase 1: Foundation & Proof of Concept
184
+ - Install and configure Web Test Runner
185
+ - Migrate simplest test suite (API - 5 tests)
186
+ - Validate core functionality
187
+ - Document learnings
188
+
189
+ #### Phase 2: Core Test Migration
190
+ - Migrate utility and transform tests
191
+ - Set up HTML fixture loading
192
+ - Configure proxy routes
193
+ - Establish patterns for common scenarios
194
+
195
+ #### Phase 3: Complex Test Migration
196
+ - Migrate browser-specific tests
197
+ - Handle replay and tracing tests
198
+ - Address edge cases
199
+ - Performance optimization
200
+
201
+ #### Phase 4: CI/CD Integration
202
+ - Update GitHub Actions workflows
203
+ - Parallel test execution
204
+ - Coverage reporting
205
+ - Remove Karma dependencies
206
+
207
+ #### Phase 5: Documentation & Cleanup
208
+ - Update developer documentation
209
+ - Remove old configurations
210
+ - Team training
211
+ - Final validation
212
+
213
+ ## Implementation Plan
214
+
215
+ ### Phase 1: Foundation Setup
216
+
217
+ #### 1.1 Install Dependencies
218
+ ```bash
219
+ npm install --save-dev @web/test-runner @web/test-runner-mocha @web/test-runner-playwright
220
+ ```
221
+
222
+ Note: `@web/test-runner-playwright` provides the Playwright integration for browser automation.
223
+
224
+ #### 1.2 Create Basic Configuration
225
+ Create `web-test-runner.config.mjs`:
226
+ ```javascript
227
+ import { playwrightLauncher } from '@web/test-runner-playwright';
228
+
229
+ export default {
230
+ files: 'test/**/*.test.js',
231
+ nodeResolve: true,
232
+
233
+ browsers: [
234
+ playwrightLauncher({ product: 'chromium' }),
235
+ ],
236
+
237
+ testFramework: {
238
+ config: {
239
+ ui: 'bdd',
240
+ timeout: 5000,
241
+ },
242
+ },
243
+ };
244
+ ```
245
+
246
+ #### 1.3 Migrate First Test Suite
247
+ Start with the API tests (smallest suite):
248
+ 1. Copy existing test file
249
+ 2. Update imports for ES modules
250
+ 3. Run with Web Test Runner
251
+ 4. Compare results with Karma output
252
+
253
+ ### Phase 2: Progressive Migration
254
+
255
+ #### 2.1 Migration Order
256
+ Based on complexity and dependencies:
257
+
258
+ 1. **Simple Tests**
259
+ - api (5 tests)
260
+ - apiUtility (14 tests)
261
+ - predicates (4 tests)
262
+
263
+ 2. **Utility Tests**
264
+ - utility (37 tests)
265
+ - transforms (42 tests)
266
+ - domUtility (15 tests)
267
+
268
+ 3. **Core Tests**
269
+ - browser.core (16 tests)
270
+ - browser.init (23 tests)
271
+ - browser.rollbar (67 tests)
272
+
273
+ 4. **Feature Tests**
274
+ - replay.* (50 tests)
275
+ - tracing.* (28 tests)
276
+
277
+ 5. **Example Tests**
278
+ - All example tests (163 tests)
279
+
280
+ #### 2.2 Configuration Enhancements
281
+ Add support for:
282
+ - HTML fixtures
283
+ - Proxy routes for `/dist/` and `/examples/`
284
+ - Custom CSP headers
285
+ - jQuery and other global dependencies
286
+
287
+ ### Phase 3: Advanced Features
288
+
289
+ #### 3.1 Parallel Execution
290
+ Configure concurrent test execution:
291
+ ```javascript
292
+ export default {
293
+ concurrency: 4,
294
+ concurrentBrowsers: 2,
295
+ // ... rest of config
296
+ };
297
+ ```
298
+
299
+ #### 3.2 Coverage Reporting
300
+ Add code coverage:
301
+ ```javascript
302
+ import { esbuildPlugin } from '@web/dev-server-esbuild';
303
+
304
+ export default {
305
+ coverage: true,
306
+ coverageConfig: {
307
+ include: ['src/**/*.js'],
308
+ threshold: {
309
+ statements: 90,
310
+ branches: 85,
311
+ functions: 85,
312
+ lines: 90,
313
+ },
314
+ },
315
+ plugins: [esbuildPlugin({ js: true })],
316
+ };
317
+ ```
318
+
319
+ ### Phase 4: CI/CD Updates
320
+
321
+ #### 4.1 GitHub Actions Workflow
322
+ Update `.github/workflows/test.yml`:
323
+ ```yaml
324
+ - name: Run browser tests
325
+ run: npm run test:browser
326
+
327
+ - name: Run server tests
328
+ run: npm run test:server
329
+ ```
330
+
331
+ #### 4.2 NPM Scripts (Direct Execution - No Grunt!)
332
+ Update package.json:
333
+ ```json
334
+ {
335
+ "scripts": {
336
+ "test": "npm run test:browser && npm run test:server",
337
+ "test:browser": "web-test-runner",
338
+ "test:server": "mocha 'test/server.*.test.mjs'",
339
+ "test:watch": "web-test-runner --watch",
340
+ "test:replay": "web-test-runner 'test/**/replay/**/*.test.js'",
341
+ "test:unit": "web-test-runner 'test/**/*.test.js' --exclude '**/integration/**'"
342
+ }
343
+ }
344
+ ```
345
+
346
+ **Command Comparison:**
347
+ | Current (via Grunt) | New (Direct) | Benefit |
348
+ | --------------------------------- | ----------------------------- | ---------------------- |
349
+ | `npm test` → `grunt test` → Karma | `npm test` → Web Test Runner | Remove 1 layer |
350
+ | `grunt test-replay` | `npm run test:replay` | Direct execution |
351
+ | `grunt karma:api` | Covered by `npm test:browser` | Unified approach |
352
+ | 273 lines of Grunt config | 0 lines | Massive simplification |
353
+
354
+ ## Technical Details
355
+
356
+ ### Handling Special Requirements
357
+
358
+ #### HTML Fixtures
359
+ ```javascript
360
+ // Current (Karma)
361
+ __html__['test/fixtures/frame.html']
362
+
363
+ // New (Web Test Runner)
364
+ import { fixture, html } from '@open-wc/testing-helpers';
365
+ const el = await fixture(html`<div>content</div>`);
366
+ ```
367
+
368
+ #### Proxy Routes
369
+ ```javascript
370
+ export default {
371
+ middleware: [
372
+ // Serve dist files
373
+ function serveDistFiles(context, next) {
374
+ if (context.path.startsWith('/dist/')) {
375
+ context.path = context.path.replace('/dist/', '/');
376
+ }
377
+ return next();
378
+ },
379
+ ],
380
+ };
381
+ ```
382
+
383
+ #### Global Dependencies
384
+ ```javascript
385
+ // For tests requiring jQuery
386
+ export default {
387
+ testRunnerHtml: testFramework => `
388
+ <html>
389
+ <body>
390
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
391
+ <script type="module" src="${testFramework}"></script>
392
+ </body>
393
+ </html>
394
+ `,
395
+ };
396
+ ```
397
+
398
+ ### Performance Optimizations
399
+
400
+ 1. **Parallel Execution**: Run up to 4 test files concurrently
401
+ 2. **Shared Dependencies**: Load common libraries once
402
+ 3. **No Bundling**: Use native ES modules
403
+ 4. **Smart Watch Mode**: Only re-run affected tests
404
+
405
+ ### Expected Performance Gains
406
+
407
+ | Metric | Current (Karma) | Expected (WTR) | Improvement |
408
+ | ----------- | --------------- | -------------- | ----------- |
409
+ | Total Time | 23 seconds | 8-10 seconds | 57-65% |
410
+ | Startup | 3 seconds | 0.5 seconds | 83% |
411
+ | Per Test | 48ms | 17ms | 65% |
412
+ | Bundle Size | 4.82MB max | 0 (native) | 100% |
413
+
414
+ ## Success Metrics
415
+
416
+ ### Quantitative Metrics
417
+ - ✅ All 478 browser tests passing
418
+ - ✅ Test execution time < 10 seconds
419
+ - ✅ Code coverage maintained at > 90%
420
+ - ✅ Zero test flakiness
421
+ - ✅ CI pipeline success rate 100%
422
+
423
+ ### Qualitative Metrics
424
+ - ✅ Improved developer experience
425
+ - ✅ Easier debugging workflow
426
+ - ✅ Simplified configuration
427
+ - ✅ Better error messages
428
+ - ✅ TypeScript-ready infrastructure
429
+
430
+ ## Rollback Plan
431
+
432
+ If issues arise during migration:
433
+
434
+ 1. **Immediate**: Tests continue running on Karma (parallel setup)
435
+ 2. **Short-term**: Revert Web Test Runner changes
436
+ 3. **Investigation**: Debug and fix issues
437
+ 4. **Retry**: Attempt migration with fixes
438
+
439
+ ### Risk Mitigation
440
+ - Keep Karma configuration until fully validated
441
+ - Run both test runners in CI during migration
442
+ - Incremental migration allows partial rollback
443
+ - Each phase independently validated
444
+
445
+ ## Next Steps
446
+
447
+ 1. **Review**: Team reviews this plan
448
+ 2. **Approval**: Get stakeholder sign-off
449
+ 3. **Setup**: Create feature branch `feature/web-test-runner`
450
+ 4. **Execute**: Begin Phase 1 implementation
451
+ 5. **Validate**: Run parallel validation until confident
452
+ 6. **Complete**: Remove Karma after full validation
453
+
454
+ ## Appendix: Learning Resources
455
+
456
+ ### For JavaScript Testing Beginners
457
+ - [MDN: Introduction to automated testing](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing)
458
+ - [Modern Web: Web Test Runner docs](https://modern-web.dev/docs/test-runner/overview/)
459
+ - [Mocha documentation](https://mochajs.org/)
460
+
461
+ ### Understanding the Migration
462
+ - Why Karma is deprecated: Maintenance burden, architectural limitations
463
+ - Why Web Test Runner: Modern architecture, native ES modules, active development
464
+ - Why keep Mocha: Minimal change, widely understood, works everywhere
465
+
466
+ ### Key Concepts
467
+ - **Test Framework**: Provides test structure (describe/it)
468
+ - **Test Runner**: Executes tests in target environment
469
+ - **Assertion Library**: Provides expectation syntax (expect/assert)
470
+ - **Test Environment**: Where tests execute (browser/Node.js)
package/Gruntfile.js CHANGED
@@ -112,7 +112,6 @@ module.exports = function (grunt) {
112
112
  grunt.loadNpmTasks('grunt-karma');
113
113
  grunt.loadNpmTasks('grunt-webpack');
114
114
  grunt.loadNpmTasks('grunt-text-replace');
115
- grunt.loadNpmTasks('grunt-vows');
116
115
 
117
116
  var rollbarJsSnippet = fs.readFileSync('dist/rollbar.snippet.js');
118
117
  var rollbarjQuerySnippet = fs.readFileSync('dist/plugins/jquery.min.js');
@@ -120,14 +119,6 @@ module.exports = function (grunt) {
120
119
  grunt.initConfig({
121
120
  pkg: pkg,
122
121
  webpack: webpackConfig,
123
- vows: {
124
- all: {
125
- options: {
126
- reporter: 'spec',
127
- },
128
- src: ['test/server.*.test.js'],
129
- },
130
- },
131
122
 
132
123
  karma: buildGruntKarmaConfig(singleRun, browserTests, reporters),
133
124
 
@@ -145,7 +136,6 @@ module.exports = function (grunt) {
145
136
  // Main rollbar snippet
146
137
  {
147
138
  from: new RegExp(
148
- /* eslint-disable-next-line no-control-regex */
149
139
  '^(.*// Rollbar Snippet)[\n\r]+(.*[\n\r])*(.*// End Rollbar Snippet)',
150
140
  'm',
151
141
  ),
@@ -157,7 +147,6 @@ module.exports = function (grunt) {
157
147
  // jQuery rollbar plugin snippet
158
148
  {
159
149
  from: new RegExp(
160
- /* eslint-disable-next-line no-control-regex */
161
150
  '^(.*// Rollbar jQuery Snippet)[\n\r]+(.*[\n\r])*(.*// End Rollbar jQuery Snippet)',
162
151
  'm',
163
152
  ),
@@ -183,13 +172,11 @@ module.exports = function (grunt) {
183
172
 
184
173
  grunt.registerTask('build', ['webpack', 'replace:snippets']);
185
174
  grunt.registerTask('default', ['build']);
186
- grunt.registerTask('test', ['test-server', 'test-browser']);
175
+ grunt.registerTask('test', [
176
+ 'test-browser',
177
+ ]);
187
178
  grunt.registerTask('release', ['build', 'copyrelease']);
188
179
 
189
- grunt.registerTask('test-server', function (_target) {
190
- var tasks = ['vows'];
191
- grunt.task.run.apply(grunt.task, tasks);
192
- });
193
180
 
194
181
  grunt.registerTask('test-browser', function (target) {
195
182
  var karmaTask = 'karma' + (target ? ':' + target : '');
@@ -197,6 +184,62 @@ module.exports = function (grunt) {
197
184
  grunt.task.run.apply(grunt.task, tasks);
198
185
  });
199
186
 
187
+ function findReplayTests() {
188
+ return Object.keys(browserTests).filter(function (testName) {
189
+ var testPath = browserTests[testName];
190
+ return (
191
+ testPath.includes('test/replay/') ||
192
+ testPath.includes('test/tracing/') ||
193
+ testPath.match(/test\/browser\.replay\..*\.test\.js/)
194
+ );
195
+ });
196
+ }
197
+
198
+ grunt.registerTask('test-replay', function () {
199
+ var replayTests = findReplayTests();
200
+
201
+ grunt.log.writeln('Running all replay-related tests:');
202
+ replayTests.forEach(function (testName) {
203
+ grunt.log.writeln('- ' + testName + ' (' + browserTests[testName] + ')');
204
+ });
205
+
206
+ replayTests.forEach(function (testName) {
207
+ grunt.task.run('karma:' + testName);
208
+ });
209
+ });
210
+
211
+ grunt.registerTask('test-replay-unit', function () {
212
+ var unitTests = findReplayTests().filter(function (testName) {
213
+ var testPath = browserTests[testName];
214
+ return testPath.includes('/replay/unit/');
215
+ });
216
+
217
+ grunt.log.writeln('Running replay unit tests:');
218
+ unitTests.forEach(function (testName) {
219
+ grunt.log.writeln('- ' + testName + ' (' + browserTests[testName] + ')');
220
+ });
221
+
222
+ unitTests.forEach(function (testName) {
223
+ grunt.task.run('karma:' + testName);
224
+ });
225
+ });
226
+
227
+ grunt.registerTask('test-replay-integration', function () {
228
+ var integrationTests = findReplayTests().filter(function (testName) {
229
+ var testPath = browserTests[testName];
230
+ return testPath.includes('/replay/integration/');
231
+ });
232
+
233
+ grunt.log.writeln('Running replay integration tests:');
234
+ integrationTests.forEach(function (testName) {
235
+ grunt.log.writeln('- ' + testName + ' (' + browserTests[testName] + ')');
236
+ });
237
+
238
+ integrationTests.forEach(function (testName) {
239
+ grunt.task.run('karma:' + testName);
240
+ });
241
+ });
242
+
200
243
  grunt.registerTask('copyrelease', function createRelease() {
201
244
  var version = pkg.version;
202
245
  var builds = ['', '.umd'];
package/Makefile CHANGED
@@ -17,8 +17,8 @@ test-server:
17
17
  @npm run test-server
18
18
  @echo ""
19
19
 
20
- test_ci:
21
- @npm run test_ci
20
+ test-ci:
21
+ @npm run test-ci
22
22
  @echo ""
23
23
 
24
- .PHONY: test test_ci
24
+ .PHONY: test test-ci
package/SECURITY.md ADDED
@@ -0,0 +1,5 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ Please report security issues to `security@rollbar.com`
@@ -0,0 +1,9 @@
1
+ {
2
+ "parserOpts": {
3
+ "ecmaVersion": 2021,
4
+ "sourceType": "module",
5
+ },
6
+ "presets": [
7
+ "@babel/preset-env"
8
+ ]
9
+ }