testdriverai 7.2.57 → 7.2.59

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.
@@ -1,52 +1,68 @@
1
1
  name: Publish
2
2
  permissions:
3
- contents: write
4
- id-token: write # Required for OIDC
3
+ contents: write
4
+ id-token: write # Required for OIDC
5
5
  on:
6
6
  push:
7
- branches: [ main ]
7
+ branches: [main]
8
8
 
9
9
  jobs:
10
10
  publish:
11
11
  runs-on: ubuntu-latest
12
-
12
+
13
13
  steps:
14
- - uses: actions/checkout@v4
15
- with:
16
- fetch-depth: 0
17
- token: ${{ secrets.GITHUB_TOKEN }}
18
-
19
- - name: Setup Node.js
20
- uses: actions/setup-node@v4
21
- with:
22
- node-version: '20'
23
- registry-url: 'https://registry.npmjs.org/'
24
-
25
- - name: Configure Git
26
- run: |
27
- git config user.name "github-actions[bot]"
28
- git config user.email "github-actions[bot]@users.noreply.github.com"
29
-
30
- - name: Install dependencies
31
- run: npm ci
32
-
33
- - name: Bump version (patch)
34
- run: npm version patch --no-git-tag-version
35
-
36
- - name: Commit and push version bump
37
- run: |
38
- git add package.json package-lock.json
39
- git commit -m "chore: bump version to $(node -p "require('./package.json').version")"
40
- git push
41
-
42
- - name: Debug NPM Token
43
- run: |
44
- echo "NPM_TOKEN is set: ${{ secrets.NPM_TOKEN != '' }}"
45
- echo "NPM_TOKEN first 4 chars: ${NPM_TOKEN:0:4}..."
46
- env:
47
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
48
-
49
- - name: Publish to npm
50
- run: npm publish --tag beta
51
- env:
52
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0
17
+ token: ${{ secrets.GITHUB_TOKEN }}
18
+
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: "20"
23
+ registry-url: "https://registry.npmjs.org/"
24
+
25
+ - name: Configure Git
26
+ run: |
27
+ git config user.name "github-actions[bot]"
28
+ git config user.email "github-actions[bot]@users.noreply.github.com"
29
+
30
+ - name: Install dependencies
31
+ run: npm ci
32
+
33
+ - name: Bump version (patch)
34
+ run: npm version patch --no-git-tag-version
35
+
36
+ - name: Generate Changelog
37
+ run: |
38
+ npx conventional-changelog-cli -p angular -i CHANGELOG.md -s
39
+ git add CHANGELOG.md
40
+
41
+ - name: Commit and push version bump
42
+ run: |
43
+ git add package.json package-lock.json
44
+ VERSION=$(node -p "require('./package.json').version")
45
+ git commit -m "chore(release): ${VERSION}"
46
+ git tag "v${VERSION}"
47
+ git push origin main
48
+ git push origin "v${VERSION}"
49
+ echo "VERSION=${VERSION}" >> $GITHUB_ENV
50
+
51
+ - name: Create GitHub Release
52
+ uses: softprops/action-gh-release@v1
53
+ with:
54
+ tag_name: v${{ env.VERSION }}
55
+ generate_release_notes: true
56
+ prerelease: false
57
+
58
+ - name: Debug NPM Token
59
+ run: |
60
+ echo "NPM_TOKEN is set: ${{ secrets.NPM_TOKEN != '' }}"
61
+ echo "NPM_TOKEN first 4 chars: ${NPM_TOKEN:0:4}..."
62
+ env:
63
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
64
+
65
+ - name: Publish to npm
66
+ run: npm publish --tag beta
67
+ env:
68
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ ## [7.2.59](https://github.com/testdriverai/testdriverai/compare/v7.2.58...v7.2.59) (2026-01-27)
2
+
3
+
4
+
5
+ ## [7.2.58](https://github.com/testdriverai/testdriverai/compare/v6.1.8...v7.2.58) (2026-01-27)
6
+
7
+
8
+ ### Reverts
9
+
10
+ * Revert "list dashcam version g" ([5037571](https://github.com/testdriverai/testdriverai/commit/5037571440c33f8966104874c542c6c57a809510))
11
+ * Revert "update discord invite" ([b5a9b99](https://github.com/testdriverai/testdriverai/commit/b5a9b9955cf2b0b07fd0ebeb6abf65f89cd3d5a8))
12
+
13
+
14
+
package/lib/sentry.js CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This module initializes Sentry for error tracking and performance monitoring.
5
5
  * It should be required at the very beginning of the CLI entry point.
6
- *
6
+ *
7
7
  * Distributed Tracing:
8
8
  * The CLI uses session-based trace IDs (MD5 hash of session ID) to link
9
9
  * CLI traces with API traces. Call setSessionTraceContext() after establishing
@@ -23,7 +23,6 @@ let currentSessionId = null;
23
23
  let emitterAttached = false;
24
24
 
25
25
  const isEnabled = () => {
26
-
27
26
  // Disable if explicitly disabled
28
27
  if (process.env.TD_TELEMETRY === "false") {
29
28
  return false;
@@ -32,19 +31,17 @@ const isEnabled = () => {
32
31
  };
33
32
 
34
33
  if (isEnabled()) {
34
+ console.log("Analytics enabled. Set TD_TELEMETRY=false to disable.");
35
35
  Sentry.init({
36
36
  dsn:
37
37
  process.env.SENTRY_DSN ||
38
38
  "https://452bd5a00dbd83a38ee8813e11c57694@o4510262629236736.ingest.us.sentry.io/4510480443637760",
39
- environment: process.env.NODE_ENV || "development",
39
+ environment: "sdk",
40
40
  release: `testdriverai@${version}`,
41
41
  sampleRate: 1.0,
42
42
  tracesSampleRate: 1.0, // Sample 20% of transactions for performance
43
43
  enableLogs: true,
44
- integrations: [
45
- Sentry.httpIntegration(),
46
- Sentry.nodeContextIntegration(),
47
- ],
44
+ integrations: [Sentry.httpIntegration(), Sentry.nodeContextIntegration()],
48
45
  // Set initial context
49
46
  initialScope: {
50
47
  tags: {
@@ -55,9 +52,6 @@ if (isEnabled()) {
55
52
  },
56
53
  // Filter out common non-errors
57
54
  beforeSend(event, hint) {
58
-
59
- console.log('sending sentry event', event);
60
-
61
55
  const error = hint.originalException;
62
56
 
63
57
  // Don't send user-initiated exits
@@ -116,7 +110,7 @@ function captureException(error, context = {}) {
116
110
  session_id: currentSessionId,
117
111
  });
118
112
  }
119
-
113
+
120
114
  if (context.tags) {
121
115
  Object.entries(context.tags).forEach(([key, value]) => {
122
116
  scope.setTag(key, value);
@@ -138,7 +132,7 @@ function captureException(error, context = {}) {
138
132
  */
139
133
  function captureMessage(message, level = "info") {
140
134
  if (!isEnabled()) return;
141
-
135
+
142
136
  Sentry.withScope((scope) => {
143
137
  // Link to session trace if available
144
138
  if (currentTraceId && currentSessionId) {
@@ -159,19 +153,19 @@ function captureMessage(message, level = "info") {
159
153
  */
160
154
  function setSessionTraceContext(sessionId) {
161
155
  if (!isEnabled() || !sessionId) return;
162
-
156
+
163
157
  // Derive trace ID from session ID (same algorithm as API)
164
158
  currentTraceId = crypto.createHash("md5").update(sessionId).digest("hex");
165
159
  currentSessionId = sessionId;
166
-
160
+
167
161
  // Set as global tag so all events include it
168
162
  Sentry.setTag("session", sessionId);
169
163
  Sentry.setTag("trace_id", currentTraceId);
170
-
164
+
171
165
  // Try to set propagation context for trace linking (may not be available in all versions)
172
166
  try {
173
167
  const scope = Sentry.getCurrentScope();
174
- if (scope && typeof scope.setPropagationContext === 'function') {
168
+ if (scope && typeof scope.setPropagationContext === "function") {
175
169
  scope.setPropagationContext({
176
170
  traceId: currentTraceId,
177
171
  spanId: currentTraceId.substring(0, 16),
@@ -180,7 +174,7 @@ function setSessionTraceContext(sessionId) {
180
174
  }
181
175
  } catch (e) {
182
176
  // Ignore errors - propagation context may not be supported
183
- console.log('Could not set propagation context:', e.message);
177
+ console.log("Could not set propagation context:", e.message);
184
178
  }
185
179
  }
186
180
 
@@ -205,104 +199,130 @@ function getTraceId() {
205
199
  * @param {EventEmitter} emitter - The event emitter to listen to
206
200
  */
207
201
  function attachLogListeners(emitter) {
208
-
209
202
  if (!isEnabled() || !emitter || emitterAttached) return;
210
-
203
+
211
204
  // Check if Sentry.logger is available
212
205
  if (!Sentry.logger) {
213
- console.log('Sentry.logger not available, skipping log listeners');
206
+ console.log("Sentry.logger not available, skipping log listeners");
214
207
  return;
215
208
  }
216
-
209
+
217
210
  emitterAttached = true;
218
211
 
219
212
  // Helper to strip ANSI codes for cleaner logs
220
213
  const stripAnsi = (str) => {
221
- if (typeof str !== 'string') return String(str);
222
- return str.replace(/\x1B[[(?);]{0,2}(;?\d)*./g, '');
214
+ if (typeof str !== "string") return String(str);
215
+ return str.replace(/\x1B[[(?);]{0,2}(;?\d)*./g, "");
223
216
  };
224
217
 
225
218
  // Helper to get current log attributes with trace context
226
219
  const getLogAttributes = (extra = {}) => {
227
220
  const attrs = { ...extra };
228
221
  if (currentSessionId) {
229
- attrs['session.id'] = currentSessionId;
222
+ attrs["session.id"] = currentSessionId;
230
223
  }
231
224
  if (currentTraceId) {
232
- attrs['sentry.trace.trace_id'] = currentTraceId;
225
+ attrs["sentry.trace.trace_id"] = currentTraceId;
233
226
  }
234
227
  // Get current user from Sentry scope
235
228
  try {
236
229
  const user = Sentry.getCurrentScope().getUser();
237
230
  if (user) {
238
- if (user.id) attrs['user.id'] = user.id;
239
- if (user.email) attrs['user.email'] = user.email;
240
- if (user.username) attrs['user.name'] = user.username;
231
+ if (user.id) attrs["user.id"] = user.id;
232
+ if (user.email) attrs["user.email"] = user.email;
233
+ if (user.username) attrs["user.name"] = user.username;
241
234
  }
242
235
  } catch (e) {
243
236
  // Ignore errors getting user
244
237
  }
245
238
  return attrs;
246
239
  };
247
-
240
+
248
241
  // Capture log:log as info logs
249
- emitter.on('log:log', (message) => {
250
- Sentry.logger.info(stripAnsi(message), getLogAttributes({ category: 'cli.log' }));
242
+ emitter.on("log:log", (message) => {
243
+ Sentry.logger.info(
244
+ stripAnsi(message),
245
+ getLogAttributes({ category: "cli.log" }),
246
+ );
251
247
  });
252
-
248
+
253
249
  // Capture log:warn as warning logs
254
- emitter.on('log:warn', (message) => {
255
- Sentry.logger.warn(stripAnsi(message), getLogAttributes({ category: 'cli.warn' }));
250
+ emitter.on("log:warn", (message) => {
251
+ Sentry.logger.warn(
252
+ stripAnsi(message),
253
+ getLogAttributes({ category: "cli.warn" }),
254
+ );
256
255
  });
257
-
256
+
258
257
  // Capture log:debug as debug logs (only in verbose mode)
259
258
  if (process.env.VERBOSE || process.env.DEBUG || process.env.TD_DEBUG) {
260
- emitter.on('log:debug', (message) => {
261
- Sentry.logger.debug(stripAnsi(message), getLogAttributes({ category: 'cli.debug' }));
259
+ emitter.on("log:debug", (message) => {
260
+ Sentry.logger.debug(
261
+ stripAnsi(message),
262
+ getLogAttributes({ category: "cli.debug" }),
263
+ );
262
264
  });
263
265
  }
264
-
266
+
265
267
  // Capture command events
266
- emitter.on('command:start', (data) => {
267
- Sentry.logger.info(`Command started: ${data?.command || data?.name || 'unknown'}`, getLogAttributes({
268
- category: 'cli.command',
269
- ...data,
270
- }));
268
+ emitter.on("command:start", (data) => {
269
+ Sentry.logger.info(
270
+ `Command started: ${data?.command || data?.name || "unknown"}`,
271
+ getLogAttributes({
272
+ category: "cli.command",
273
+ ...data,
274
+ }),
275
+ );
271
276
  });
272
-
273
- emitter.on('command:error', (data) => {
274
- Sentry.logger.error(`Command error: ${data?.message || data?.error || 'unknown'}`, getLogAttributes({
275
- category: 'cli.command',
276
- ...data,
277
- }));
277
+
278
+ emitter.on("command:error", (data) => {
279
+ Sentry.logger.error(
280
+ `Command error: ${data?.message || data?.error || "unknown"}`,
281
+ getLogAttributes({
282
+ category: "cli.command",
283
+ ...data,
284
+ }),
285
+ );
278
286
  });
279
-
287
+
280
288
  // Capture step events
281
- emitter.on('step:start', (data) => {
282
- Sentry.logger.info(`Step started: ${data?.step || data?.name || 'unknown'}`, getLogAttributes({
283
- category: 'cli.step',
284
- }));
289
+ emitter.on("step:start", (data) => {
290
+ Sentry.logger.info(
291
+ `Step started: ${data?.step || data?.name || "unknown"}`,
292
+ getLogAttributes({
293
+ category: "cli.step",
294
+ }),
295
+ );
285
296
  });
286
-
287
- emitter.on('step:error', (data) => {
288
- Sentry.logger.error(`Step error: ${data?.message || data?.error || 'unknown'}`, getLogAttributes({
289
- category: 'cli.step',
290
- ...data,
291
- }));
297
+
298
+ emitter.on("step:error", (data) => {
299
+ Sentry.logger.error(
300
+ `Step error: ${data?.message || data?.error || "unknown"}`,
301
+ getLogAttributes({
302
+ category: "cli.step",
303
+ ...data,
304
+ }),
305
+ );
292
306
  });
293
-
307
+
294
308
  // Capture test events
295
- emitter.on('test:start', (data) => {
296
- Sentry.logger.info(`Test started: ${data?.name || 'unknown'}`, getLogAttributes({
297
- category: 'cli.test',
298
- }));
309
+ emitter.on("test:start", (data) => {
310
+ Sentry.logger.info(
311
+ `Test started: ${data?.name || "unknown"}`,
312
+ getLogAttributes({
313
+ category: "cli.test",
314
+ }),
315
+ );
299
316
  });
300
-
301
- emitter.on('test:error', (data) => {
302
- Sentry.logger.error(`Test error: ${data?.message || data?.error || 'unknown'}`, getLogAttributes({
303
- category: 'cli.test',
304
- ...data,
305
- }));
317
+
318
+ emitter.on("test:error", (data) => {
319
+ Sentry.logger.error(
320
+ `Test error: ${data?.message || data?.error || "unknown"}`,
321
+ getLogAttributes({
322
+ category: "cli.test",
323
+ ...data,
324
+ }),
325
+ );
306
326
  });
307
327
  }
308
328
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.2.57",
3
+ "version": "7.2.59",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",