dd-trace 5.41.1 → 5.42.0
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/LICENSE-3rdparty.csv +1 -0
- package/index.d.ts +8 -1
- package/package.json +6 -3
- package/packages/datadog-esbuild/index.js +3 -1
- package/packages/datadog-instrumentations/src/cucumber.js +37 -29
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +102 -0
- package/packages/datadog-instrumentations/src/{check_require_cache.js → helpers/check-require-cache.js} +2 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +4 -1
- package/packages/datadog-instrumentations/src/jest.js +72 -49
- package/packages/datadog-instrumentations/src/langchain.js +29 -10
- package/packages/datadog-instrumentations/src/mocha/main.js +53 -34
- package/packages/datadog-instrumentations/src/mocha/utils.js +34 -24
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -8
- package/packages/datadog-instrumentations/src/openai.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +37 -30
- package/packages/datadog-instrumentations/src/vitest.js +64 -29
- package/packages/datadog-plugin-cucumber/src/index.js +13 -4
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +41 -35
- package/packages/datadog-plugin-cypress/src/plugin.js +10 -0
- package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +195 -0
- package/packages/datadog-plugin-jest/src/index.js +18 -6
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +4 -1
- package/packages/datadog-plugin-mocha/src/index.js +13 -4
- package/packages/datadog-plugin-playwright/src/index.js +19 -5
- package/packages/datadog-plugin-vitest/src/index.js +41 -17
- package/packages/dd-trace/src/appsec/api_security_sampler.js +7 -3
- package/packages/dd-trace/src/appsec/blocking.js +23 -16
- package/packages/dd-trace/src/appsec/graphql.js +13 -6
- package/packages/dd-trace/src/appsec/rasp/utils.js +0 -1
- package/packages/dd-trace/src/appsec/reporter.js +35 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -3
- package/packages/dd-trace/src/appsec/telemetry/index.js +5 -1
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -1
- package/packages/dd-trace/src/appsec/telemetry/waf.js +16 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +43 -13
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +15 -14
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -2
- package/packages/dd-trace/src/ci-visibility/telemetry.js +2 -1
- package/packages/dd-trace/src/ci-visibility/{quarantined-tests/get-quarantined-tests.js → test-management/get-test-management-tests.js} +5 -5
- package/packages/dd-trace/src/config.js +11 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -2
- package/packages/dd-trace/src/lambda/runtime/patch.js +5 -3
- package/packages/dd-trace/src/lambda/runtime/ritm.js +13 -18
- package/packages/dd-trace/src/llmobs/plugins/openai.js +27 -2
- package/packages/dd-trace/src/opentracing/span.js +3 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +38 -10
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/git.js +7 -3
- package/packages/dd-trace/src/plugins/util/test.js +10 -0
- package/packages/dd-trace/src/plugins/util/web.js +5 -2
- package/packages/dd-trace/src/priority_sampler.js +116 -15
- package/packages/dd-trace/src/sampler.js +9 -0
- package/packages/dd-trace/src/standalone/product.js +6 -2
- package/packages/dd-trace/src/startup-log.js +2 -1
- package/packages/dd-trace/src/telemetry/metrics.js +0 -8
- package/packages/dd-trace/src/tracer.js +1 -1
- /package/packages/datadog-instrumentations/src/{utils/src → helpers}/extract-package-and-module-path.js +0 -0
|
@@ -13,7 +13,7 @@ const testSessionFinishCh = channel('ci:playwright:session:finish')
|
|
|
13
13
|
|
|
14
14
|
const libraryConfigurationCh = channel('ci:playwright:library-configuration')
|
|
15
15
|
const knownTestsCh = channel('ci:playwright:known-tests')
|
|
16
|
-
const
|
|
16
|
+
const testManagementTestsCh = channel('ci:playwright:test-management-tests')
|
|
17
17
|
|
|
18
18
|
const testSuiteStartCh = channel('ci:playwright:test-suite:start')
|
|
19
19
|
const testSuiteFinishCh = channel('ci:playwright:test-suite:finish')
|
|
@@ -42,23 +42,19 @@ let earlyFlakeDetectionNumRetries = 0
|
|
|
42
42
|
let isFlakyTestRetriesEnabled = false
|
|
43
43
|
let flakyTestRetriesCount = 0
|
|
44
44
|
let knownTests = {}
|
|
45
|
-
let
|
|
46
|
-
let
|
|
45
|
+
let isTestManagementTestsEnabled = false
|
|
46
|
+
let testManagementTests = {}
|
|
47
47
|
let rootDir = ''
|
|
48
48
|
const MINIMUM_SUPPORTED_VERSION_RANGE_EFD = '>=1.38.0'
|
|
49
49
|
|
|
50
|
-
function
|
|
50
|
+
function getTestProperties (test) {
|
|
51
51
|
const testName = getTestFullname(test)
|
|
52
52
|
const testSuite = getTestSuitePath(test._requireFile, rootDir)
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
?.playwright
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
?.tests
|
|
59
|
-
?.[testName]
|
|
60
|
-
?.properties
|
|
61
|
-
?.quarantined
|
|
54
|
+
const { disabled, quarantined } =
|
|
55
|
+
testManagementTests?.playwright?.suites?.[testSuite]?.tests?.[testName]?.properties || {}
|
|
56
|
+
|
|
57
|
+
return { disabled, quarantined }
|
|
62
58
|
}
|
|
63
59
|
|
|
64
60
|
function isNewTest (test) {
|
|
@@ -283,7 +279,13 @@ function testBeginHandler (test, browserName) {
|
|
|
283
279
|
const testAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
284
280
|
testToAr.set(test, testAsyncResource)
|
|
285
281
|
testAsyncResource.runInAsyncScope(() => {
|
|
286
|
-
testStartCh.publish({
|
|
282
|
+
testStartCh.publish({
|
|
283
|
+
testName,
|
|
284
|
+
testSuiteAbsolutePath,
|
|
285
|
+
testSourceLine,
|
|
286
|
+
browserName,
|
|
287
|
+
isDisabled: test._ddIsDisabled
|
|
288
|
+
})
|
|
287
289
|
})
|
|
288
290
|
}
|
|
289
291
|
|
|
@@ -442,12 +444,12 @@ function runnerHook (runnerExport, playwrightVersion) {
|
|
|
442
444
|
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
443
445
|
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
444
446
|
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
445
|
-
|
|
447
|
+
isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
446
448
|
}
|
|
447
449
|
} catch (e) {
|
|
448
450
|
isEarlyFlakeDetectionEnabled = false
|
|
449
451
|
isKnownTestsEnabled = false
|
|
450
|
-
|
|
452
|
+
isTestManagementTestsEnabled = false
|
|
451
453
|
log.error('Playwright session start error', e)
|
|
452
454
|
}
|
|
453
455
|
|
|
@@ -467,17 +469,17 @@ function runnerHook (runnerExport, playwrightVersion) {
|
|
|
467
469
|
}
|
|
468
470
|
}
|
|
469
471
|
|
|
470
|
-
if (
|
|
472
|
+
if (isTestManagementTestsEnabled && satisfies(playwrightVersion, MINIMUM_SUPPORTED_VERSION_RANGE_EFD)) {
|
|
471
473
|
try {
|
|
472
|
-
const { err,
|
|
474
|
+
const { err, testManagementTests: receivedTestManagementTests } = await getChannelPromise(testManagementTestsCh)
|
|
473
475
|
if (!err) {
|
|
474
|
-
|
|
476
|
+
testManagementTests = receivedTestManagementTests
|
|
475
477
|
} else {
|
|
476
|
-
|
|
478
|
+
isTestManagementTestsEnabled = false
|
|
477
479
|
}
|
|
478
480
|
} catch (err) {
|
|
479
|
-
|
|
480
|
-
log.error('Playwright
|
|
481
|
+
isTestManagementTestsEnabled = false
|
|
482
|
+
log.error('Playwright test management tests error', err)
|
|
481
483
|
}
|
|
482
484
|
}
|
|
483
485
|
|
|
@@ -513,7 +515,7 @@ function runnerHook (runnerExport, playwrightVersion) {
|
|
|
513
515
|
testSessionFinishCh.publish({
|
|
514
516
|
status: STATUS_TO_TEST_STATUS[sessionStatus],
|
|
515
517
|
isEarlyFlakeDetectionEnabled,
|
|
516
|
-
|
|
518
|
+
isTestManagementTestsEnabled,
|
|
517
519
|
onDone
|
|
518
520
|
})
|
|
519
521
|
})
|
|
@@ -523,7 +525,7 @@ function runnerHook (runnerExport, playwrightVersion) {
|
|
|
523
525
|
remainingTestsByFile = {}
|
|
524
526
|
|
|
525
527
|
// TODO: we can trick playwright into thinking the session passed by returning
|
|
526
|
-
// 'passed' here. We might be able to use this for both EFD and
|
|
528
|
+
// 'passed' here. We might be able to use this for both EFD and Test Management tests.
|
|
527
529
|
return runAllTestsReturn
|
|
528
530
|
})
|
|
529
531
|
|
|
@@ -594,19 +596,24 @@ addHook({
|
|
|
594
596
|
const oldCreateRootSuite = loadUtilsPackage.createRootSuite
|
|
595
597
|
|
|
596
598
|
async function newCreateRootSuite () {
|
|
597
|
-
if (!isKnownTestsEnabled && !
|
|
599
|
+
if (!isKnownTestsEnabled && !isTestManagementTestsEnabled) {
|
|
598
600
|
return oldCreateRootSuite.apply(this, arguments)
|
|
599
601
|
}
|
|
600
602
|
const rootSuite = await oldCreateRootSuite.apply(this, arguments)
|
|
601
603
|
|
|
602
604
|
const allTests = rootSuite.allTests()
|
|
603
605
|
|
|
604
|
-
if (
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
606
|
+
if (isTestManagementTestsEnabled) {
|
|
607
|
+
for (const test of allTests) {
|
|
608
|
+
const testProperties = getTestProperties(test)
|
|
609
|
+
if (testProperties.disabled) {
|
|
610
|
+
test._ddIsDisabled = true
|
|
611
|
+
test.expectedStatus = 'skipped'
|
|
612
|
+
} else if (testProperties.quarantined) {
|
|
613
|
+
test._ddIsQuarantined = true
|
|
614
|
+
test.expectedStatus = 'skipped'
|
|
615
|
+
}
|
|
616
|
+
}
|
|
610
617
|
}
|
|
611
618
|
|
|
612
619
|
if (isKnownTestsEnabled) {
|
|
@@ -9,6 +9,7 @@ const testPassCh = channel('ci:vitest:test:pass')
|
|
|
9
9
|
const testErrorCh = channel('ci:vitest:test:error')
|
|
10
10
|
const testSkipCh = channel('ci:vitest:test:skip')
|
|
11
11
|
const isNewTestCh = channel('ci:vitest:test:is-new')
|
|
12
|
+
const isDisabledCh = channel('ci:vitest:test:is-disabled')
|
|
12
13
|
const isQuarantinedCh = channel('ci:vitest:test:is-quarantined')
|
|
13
14
|
|
|
14
15
|
// test suite hooks
|
|
@@ -22,11 +23,12 @@ const testSessionFinishCh = channel('ci:vitest:session:finish')
|
|
|
22
23
|
const libraryConfigurationCh = channel('ci:vitest:library-configuration')
|
|
23
24
|
const knownTestsCh = channel('ci:vitest:known-tests')
|
|
24
25
|
const isEarlyFlakeDetectionFaultyCh = channel('ci:vitest:is-early-flake-detection-faulty')
|
|
25
|
-
const
|
|
26
|
+
const testManagementTestsCh = channel('ci:vitest:test-management-tests')
|
|
26
27
|
|
|
27
28
|
const taskToAsync = new WeakMap()
|
|
28
29
|
const taskToStatuses = new WeakMap()
|
|
29
30
|
const newTasks = new WeakSet()
|
|
31
|
+
const disabledTasks = new WeakSet()
|
|
30
32
|
const quarantinedTasks = new WeakSet()
|
|
31
33
|
let isRetryReasonEfd = false
|
|
32
34
|
const switchedStatuses = new WeakSet()
|
|
@@ -50,8 +52,9 @@ function getProvidedContext () {
|
|
|
50
52
|
_ddKnownTests: knownTests,
|
|
51
53
|
_ddEarlyFlakeDetectionNumRetries: numRepeats,
|
|
52
54
|
_ddIsKnownTestsEnabled: isKnownTestsEnabled,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
_ddIsTestManagementTestsEnabled: isTestManagementTestsEnabled,
|
|
56
|
+
_ddTestManagementTests: testManagementTests,
|
|
57
|
+
_ddIsFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled
|
|
55
58
|
} = globalThis.__vitest_worker__.providedContext
|
|
56
59
|
|
|
57
60
|
return {
|
|
@@ -60,8 +63,9 @@ function getProvidedContext () {
|
|
|
60
63
|
knownTests,
|
|
61
64
|
numRepeats,
|
|
62
65
|
isKnownTestsEnabled,
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
isTestManagementTestsEnabled,
|
|
67
|
+
testManagementTests,
|
|
68
|
+
isFlakyTestRetriesEnabled
|
|
65
69
|
}
|
|
66
70
|
} catch (e) {
|
|
67
71
|
log.error('Vitest workers could not parse provided context, so some features will not work.')
|
|
@@ -71,8 +75,8 @@ function getProvidedContext () {
|
|
|
71
75
|
knownTests: {},
|
|
72
76
|
numRepeats: 0,
|
|
73
77
|
isKnownTestsEnabled: false,
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
isTestManagementTestsEnabled: false,
|
|
79
|
+
testManagementTests: {}
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
82
|
}
|
|
@@ -167,10 +171,10 @@ function getSortWrapper (sort) {
|
|
|
167
171
|
let earlyFlakeDetectionNumRetries = 0
|
|
168
172
|
let isEarlyFlakeDetectionFaulty = false
|
|
169
173
|
let isKnownTestsEnabled = false
|
|
170
|
-
let
|
|
174
|
+
let isTestManagementTestsEnabled = false
|
|
171
175
|
let isDiEnabled = false
|
|
172
176
|
let knownTests = {}
|
|
173
|
-
let
|
|
177
|
+
let testManagementTests = {}
|
|
174
178
|
|
|
175
179
|
try {
|
|
176
180
|
const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
|
|
@@ -181,7 +185,7 @@ function getSortWrapper (sort) {
|
|
|
181
185
|
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
182
186
|
isDiEnabled = libraryConfig.isDiEnabled
|
|
183
187
|
isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
|
|
184
|
-
|
|
188
|
+
isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
185
189
|
}
|
|
186
190
|
} catch (e) {
|
|
187
191
|
isFlakyTestRetriesEnabled = false
|
|
@@ -192,6 +196,12 @@ function getSortWrapper (sort) {
|
|
|
192
196
|
|
|
193
197
|
if (isFlakyTestRetriesEnabled && !this.ctx.config.retry && flakyTestRetriesCount > 0) {
|
|
194
198
|
this.ctx.config.retry = flakyTestRetriesCount
|
|
199
|
+
try {
|
|
200
|
+
const workspaceProject = this.ctx.getCoreWorkspaceProject()
|
|
201
|
+
workspaceProject._provided._ddIsFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
|
|
202
|
+
} catch (e) {
|
|
203
|
+
log.warn('Could not send library configuration to workers.')
|
|
204
|
+
}
|
|
195
205
|
}
|
|
196
206
|
|
|
197
207
|
if (isKnownTestsEnabled) {
|
|
@@ -241,20 +251,20 @@ function getSortWrapper (sort) {
|
|
|
241
251
|
}
|
|
242
252
|
}
|
|
243
253
|
|
|
244
|
-
if (
|
|
245
|
-
const { err,
|
|
254
|
+
if (isTestManagementTestsEnabled) {
|
|
255
|
+
const { err, testManagementTests: receivedTestManagementTests } = await getChannelPromise(testManagementTestsCh)
|
|
246
256
|
if (!err) {
|
|
247
|
-
|
|
257
|
+
testManagementTests = receivedTestManagementTests
|
|
248
258
|
try {
|
|
249
259
|
const workspaceProject = this.ctx.getCoreWorkspaceProject()
|
|
250
|
-
workspaceProject._provided.
|
|
251
|
-
workspaceProject._provided.
|
|
260
|
+
workspaceProject._provided._ddIsTestManagementTestsEnabled = isTestManagementTestsEnabled
|
|
261
|
+
workspaceProject._provided._ddTestManagementTests = testManagementTests
|
|
252
262
|
} catch (e) {
|
|
253
|
-
log.warn('Could not send
|
|
263
|
+
log.warn('Could not send test management tests to workers so Test Management will not work.')
|
|
254
264
|
}
|
|
255
265
|
} else {
|
|
256
|
-
|
|
257
|
-
log.error('Could not get
|
|
266
|
+
isTestManagementTestsEnabled = false
|
|
267
|
+
log.error('Could not get test management tests.')
|
|
258
268
|
}
|
|
259
269
|
}
|
|
260
270
|
|
|
@@ -292,7 +302,7 @@ function getSortWrapper (sort) {
|
|
|
292
302
|
error,
|
|
293
303
|
isEarlyFlakeDetectionEnabled,
|
|
294
304
|
isEarlyFlakeDetectionFaulty,
|
|
295
|
-
|
|
305
|
+
isTestManagementTestsEnabled,
|
|
296
306
|
onFinish
|
|
297
307
|
})
|
|
298
308
|
})
|
|
@@ -337,9 +347,25 @@ addHook({
|
|
|
337
347
|
knownTests,
|
|
338
348
|
isEarlyFlakeDetectionEnabled,
|
|
339
349
|
isKnownTestsEnabled,
|
|
340
|
-
numRepeats
|
|
350
|
+
numRepeats,
|
|
351
|
+
isTestManagementTestsEnabled,
|
|
352
|
+
testManagementTests
|
|
341
353
|
} = getProvidedContext()
|
|
342
354
|
|
|
355
|
+
if (isTestManagementTestsEnabled) {
|
|
356
|
+
isDisabledCh.publish({
|
|
357
|
+
testManagementTests,
|
|
358
|
+
testSuiteAbsolutePath: task.file.filepath,
|
|
359
|
+
testName,
|
|
360
|
+
onDone: (isTestDisabled) => {
|
|
361
|
+
if (isTestDisabled) {
|
|
362
|
+
disabledTasks.add(task)
|
|
363
|
+
task.mode = 'skip'
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
|
|
343
369
|
if (isKnownTestsEnabled) {
|
|
344
370
|
isNewTestCh.publish({
|
|
345
371
|
knownTests,
|
|
@@ -364,7 +390,7 @@ addHook({
|
|
|
364
390
|
// `onAfterRunTask` is run after all repetitions or attempts are run
|
|
365
391
|
// `onAfterRunTask` is an async function
|
|
366
392
|
shimmer.wrap(VitestTestRunner.prototype, 'onAfterRunTask', onAfterRunTask => function (task) {
|
|
367
|
-
const { isEarlyFlakeDetectionEnabled,
|
|
393
|
+
const { isEarlyFlakeDetectionEnabled, isTestManagementTestsEnabled } = getProvidedContext()
|
|
368
394
|
|
|
369
395
|
if (isEarlyFlakeDetectionEnabled && taskToStatuses.has(task)) {
|
|
370
396
|
const statuses = taskToStatuses.get(task)
|
|
@@ -377,7 +403,7 @@ addHook({
|
|
|
377
403
|
}
|
|
378
404
|
}
|
|
379
405
|
|
|
380
|
-
if (
|
|
406
|
+
if (isTestManagementTestsEnabled) {
|
|
381
407
|
if (quarantinedTasks.has(task)) {
|
|
382
408
|
task.result.state = 'pass'
|
|
383
409
|
}
|
|
@@ -400,17 +426,17 @@ addHook({
|
|
|
400
426
|
isKnownTestsEnabled,
|
|
401
427
|
isEarlyFlakeDetectionEnabled,
|
|
402
428
|
isDiEnabled,
|
|
403
|
-
|
|
404
|
-
|
|
429
|
+
isTestManagementTestsEnabled,
|
|
430
|
+
testManagementTests
|
|
405
431
|
} = getProvidedContext()
|
|
406
432
|
|
|
407
433
|
if (isKnownTestsEnabled) {
|
|
408
434
|
isNew = newTasks.has(task)
|
|
409
435
|
}
|
|
410
436
|
|
|
411
|
-
if (
|
|
437
|
+
if (isTestManagementTestsEnabled) {
|
|
412
438
|
isQuarantinedCh.publish({
|
|
413
|
-
|
|
439
|
+
testManagementTests,
|
|
414
440
|
testSuiteAbsolutePath: task.file.filepath,
|
|
415
441
|
testName,
|
|
416
442
|
onDone: (isTestQuarantined) => {
|
|
@@ -624,9 +650,16 @@ addHook({
|
|
|
624
650
|
// From >=3.0.1, the first arguments changes from a string to an object containing the filepath
|
|
625
651
|
const testSuiteAbsolutePath = testPaths[0]?.filepath || testPaths[0]
|
|
626
652
|
|
|
653
|
+
const { isEarlyFlakeDetectionEnabled, isFlakyTestRetriesEnabled } = getProvidedContext()
|
|
654
|
+
|
|
627
655
|
const testSuiteAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
628
656
|
testSuiteAsyncResource.runInAsyncScope(() => {
|
|
629
|
-
testSuiteStartCh.publish({
|
|
657
|
+
testSuiteStartCh.publish({
|
|
658
|
+
testSuiteAbsolutePath,
|
|
659
|
+
frameworkVersion,
|
|
660
|
+
isFlakyTestRetriesEnabled,
|
|
661
|
+
isEarlyFlakeDetectionEnabled
|
|
662
|
+
})
|
|
630
663
|
})
|
|
631
664
|
const startTestsResponse = await startTests.apply(this, arguments)
|
|
632
665
|
|
|
@@ -651,7 +684,8 @@ addHook({
|
|
|
651
684
|
testSkipCh.publish({
|
|
652
685
|
testName: getTestName(task),
|
|
653
686
|
testSuiteAbsolutePath: task.file.filepath,
|
|
654
|
-
isNew: newTasks.has(task)
|
|
687
|
+
isNew: newTasks.has(task),
|
|
688
|
+
isDisabled: disabledTasks.has(task)
|
|
655
689
|
})
|
|
656
690
|
} else if (state === 'pass' && !isSwitchedStatus) {
|
|
657
691
|
if (testAsyncResource) {
|
|
@@ -681,7 +715,8 @@ addHook({
|
|
|
681
715
|
testSkipCh.publish({
|
|
682
716
|
testName: getTestName(task),
|
|
683
717
|
testSuiteAbsolutePath: task.file.filepath,
|
|
684
|
-
isNew: newTasks.has(task)
|
|
718
|
+
isNew: newTasks.has(task),
|
|
719
|
+
isDisabled: disabledTasks.has(task)
|
|
685
720
|
})
|
|
686
721
|
}
|
|
687
722
|
})
|
|
@@ -29,7 +29,8 @@ const {
|
|
|
29
29
|
CUCUMBER_IS_PARALLEL,
|
|
30
30
|
TEST_RETRY_REASON,
|
|
31
31
|
TEST_MANAGEMENT_ENABLED,
|
|
32
|
-
TEST_MANAGEMENT_IS_QUARANTINED
|
|
32
|
+
TEST_MANAGEMENT_IS_QUARANTINED,
|
|
33
|
+
TEST_MANAGEMENT_IS_DISABLED
|
|
33
34
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
34
35
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
35
36
|
const { COMPONENT, ERROR_MESSAGE } = require('../../dd-trace/src/constants')
|
|
@@ -86,7 +87,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
86
87
|
hasForcedToRunSuites,
|
|
87
88
|
isEarlyFlakeDetectionEnabled,
|
|
88
89
|
isEarlyFlakeDetectionFaulty,
|
|
89
|
-
|
|
90
|
+
isTestManagementTestsEnabled,
|
|
90
91
|
isParallel
|
|
91
92
|
}) => {
|
|
92
93
|
const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.libraryConfig || {}
|
|
@@ -113,7 +114,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
113
114
|
if (isParallel) {
|
|
114
115
|
this.testSessionSpan.setTag(CUCUMBER_IS_PARALLEL, 'true')
|
|
115
116
|
}
|
|
116
|
-
if (
|
|
117
|
+
if (isTestManagementTestsEnabled) {
|
|
117
118
|
this.testSessionSpan.setTag(TEST_MANAGEMENT_ENABLED, 'true')
|
|
118
119
|
}
|
|
119
120
|
|
|
@@ -124,7 +125,10 @@ class CucumberPlugin extends CiPlugin {
|
|
|
124
125
|
this.testSessionSpan.finish()
|
|
125
126
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
126
127
|
finishAllTraceSpans(this.testSessionSpan)
|
|
127
|
-
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
128
|
+
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
129
|
+
provider: this.ciProviderName,
|
|
130
|
+
autoInjected: !!process.env.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER
|
|
131
|
+
})
|
|
128
132
|
|
|
129
133
|
this.libraryConfig = null
|
|
130
134
|
this.tracer._exporter.flush()
|
|
@@ -324,6 +328,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
324
328
|
isNew,
|
|
325
329
|
isEfdRetry,
|
|
326
330
|
isFlakyRetry,
|
|
331
|
+
isDisabled,
|
|
327
332
|
isQuarantined
|
|
328
333
|
}) => {
|
|
329
334
|
const span = storage('legacy').getStore().span
|
|
@@ -353,6 +358,10 @@ class CucumberPlugin extends CiPlugin {
|
|
|
353
358
|
span.setTag(TEST_IS_RETRY, 'true')
|
|
354
359
|
}
|
|
355
360
|
|
|
361
|
+
if (isDisabled) {
|
|
362
|
+
span.setTag(TEST_MANAGEMENT_IS_DISABLED, 'true')
|
|
363
|
+
}
|
|
364
|
+
|
|
356
365
|
if (isQuarantined) {
|
|
357
366
|
span.setTag(TEST_MANAGEMENT_IS_QUARANTINED, 'true')
|
|
358
367
|
}
|
|
@@ -35,7 +35,11 @@ const {
|
|
|
35
35
|
TEST_RETRY_REASON,
|
|
36
36
|
DD_TEST_IS_USER_PROVIDED_SERVICE,
|
|
37
37
|
TEST_MANAGEMENT_IS_QUARANTINED,
|
|
38
|
-
TEST_MANAGEMENT_ENABLED
|
|
38
|
+
TEST_MANAGEMENT_ENABLED,
|
|
39
|
+
TEST_MANAGEMENT_IS_DISABLED,
|
|
40
|
+
DD_CAPABILITIES_EARLY_FLAKE_DETECTION,
|
|
41
|
+
DD_CAPABILITIES_AUTO_TEST_RETRIES,
|
|
42
|
+
DD_CAPABILITIES_TEST_IMPACT_ANALYSIS
|
|
39
43
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
40
44
|
const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
|
|
41
45
|
const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
|
|
@@ -154,15 +158,15 @@ function getKnownTests (tracer, testConfiguration) {
|
|
|
154
158
|
})
|
|
155
159
|
}
|
|
156
160
|
|
|
157
|
-
function
|
|
161
|
+
function getTestManagementTests (tracer, testConfiguration) {
|
|
158
162
|
return new Promise(resolve => {
|
|
159
|
-
if (!tracer._tracer._exporter?.
|
|
163
|
+
if (!tracer._tracer._exporter?.getTestManagementTests) {
|
|
160
164
|
return resolve({ err: new Error('Test Optimization was not initialized correctly') })
|
|
161
165
|
}
|
|
162
|
-
tracer._tracer._exporter.
|
|
166
|
+
tracer._tracer._exporter.getTestManagementTests(testConfiguration, (err, testManagementTests) => {
|
|
163
167
|
resolve({
|
|
164
168
|
err,
|
|
165
|
-
|
|
169
|
+
testManagementTests
|
|
166
170
|
})
|
|
167
171
|
})
|
|
168
172
|
})
|
|
@@ -257,7 +261,7 @@ class CypressPlugin {
|
|
|
257
261
|
isFlakyTestRetriesEnabled,
|
|
258
262
|
flakyTestRetriesCount,
|
|
259
263
|
isKnownTestsEnabled,
|
|
260
|
-
|
|
264
|
+
isTestManagementEnabled
|
|
261
265
|
}
|
|
262
266
|
} = libraryConfigurationResponse
|
|
263
267
|
this.isSuitesSkippingEnabled = isSuitesSkippingEnabled
|
|
@@ -268,22 +272,18 @@ class CypressPlugin {
|
|
|
268
272
|
if (isFlakyTestRetriesEnabled) {
|
|
269
273
|
this.cypressConfig.retries.runMode = flakyTestRetriesCount
|
|
270
274
|
}
|
|
271
|
-
this.
|
|
275
|
+
this.isTestManagementTestsEnabled = isTestManagementEnabled
|
|
272
276
|
}
|
|
273
277
|
return this.cypressConfig
|
|
274
278
|
})
|
|
275
279
|
return this.libraryConfigurationPromise
|
|
276
280
|
}
|
|
277
281
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
?.cypress
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
?.tests
|
|
284
|
-
?.[testName]
|
|
285
|
-
?.properties
|
|
286
|
-
?.quarantined
|
|
282
|
+
getTestProperties (testSuite, testName) {
|
|
283
|
+
const { disabled: isDisabled, quarantined: isQuarantined } =
|
|
284
|
+
this.testManagementTests?.cypress?.suites?.[testSuite]?.tests?.[testName]?.properties || {}
|
|
285
|
+
|
|
286
|
+
return { isDisabled, isQuarantined }
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
getTestSuiteSpan ({ testSuite, testSuiteAbsolutePath }) {
|
|
@@ -418,16 +418,16 @@ class CypressPlugin {
|
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
-
if (this.
|
|
422
|
-
const
|
|
421
|
+
if (this.isTestManagementTestsEnabled) {
|
|
422
|
+
const testManagementTestsResponse = await getTestManagementTests(
|
|
423
423
|
this.tracer,
|
|
424
424
|
this.testConfiguration
|
|
425
425
|
)
|
|
426
|
-
if (
|
|
427
|
-
log.error('Cypress
|
|
428
|
-
this.
|
|
426
|
+
if (testManagementTestsResponse.err) {
|
|
427
|
+
log.error('Cypress test management tests response error', testManagementTestsResponse.err)
|
|
428
|
+
this.isTestManagementTestsEnabled = false
|
|
429
429
|
} else {
|
|
430
|
-
this.
|
|
430
|
+
this.testManagementTests = testManagementTestsResponse.testManagementTests
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
433
|
|
|
@@ -452,14 +452,21 @@ class CypressPlugin {
|
|
|
452
452
|
|
|
453
453
|
const testSessionName = getTestSessionName(this.tracer._tracer._config, this.command, this.testEnvironmentMetadata)
|
|
454
454
|
|
|
455
|
-
if (this.tracer._tracer._exporter?.
|
|
455
|
+
if (this.tracer._tracer._exporter?.addMetadataTags) {
|
|
456
456
|
const metadataTags = {}
|
|
457
457
|
for (const testLevel of TEST_LEVEL_EVENT_TYPES) {
|
|
458
458
|
metadataTags[testLevel] = {
|
|
459
459
|
[TEST_SESSION_NAME]: testSessionName
|
|
460
460
|
}
|
|
461
461
|
}
|
|
462
|
-
|
|
462
|
+
metadataTags.test = {
|
|
463
|
+
...metadataTags.test,
|
|
464
|
+
[DD_CAPABILITIES_TEST_IMPACT_ANALYSIS]: this.isSuitesSkippingEnabled ? 'true' : 'false',
|
|
465
|
+
[DD_CAPABILITIES_EARLY_FLAKE_DETECTION]: this.isEarlyFlakeDetectionEnabled ? 'true' : 'false',
|
|
466
|
+
[DD_CAPABILITIES_AUTO_TEST_RETRIES]: this.isFlakyTestRetriesEnabled ? 'true' : 'false'
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
this.tracer._tracer._exporter.addMetadataTags(metadataTags)
|
|
463
470
|
}
|
|
464
471
|
|
|
465
472
|
this.testSessionSpan = this.tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_session`, {
|
|
@@ -509,7 +516,7 @@ class CypressPlugin {
|
|
|
509
516
|
}
|
|
510
517
|
)
|
|
511
518
|
|
|
512
|
-
if (this.
|
|
519
|
+
if (this.isTestManagementTestsEnabled) {
|
|
513
520
|
this.testSessionSpan.setTag(TEST_MANAGEMENT_ENABLED, 'true')
|
|
514
521
|
}
|
|
515
522
|
|
|
@@ -518,7 +525,8 @@ class CypressPlugin {
|
|
|
518
525
|
this.testSessionSpan.finish()
|
|
519
526
|
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
520
527
|
incrementCountMetric(TELEMETRY_TEST_SESSION, {
|
|
521
|
-
provider: this.ciProviderName
|
|
528
|
+
provider: this.ciProviderName,
|
|
529
|
+
autoInjected: !!process.env.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER
|
|
522
530
|
})
|
|
523
531
|
|
|
524
532
|
finishAllTraceSpans(this.testSessionSpan)
|
|
@@ -588,9 +596,11 @@ class CypressPlugin {
|
|
|
588
596
|
skippedTestSpan.setTag(ITR_CORRELATION_ID, this.itrCorrelationId)
|
|
589
597
|
}
|
|
590
598
|
|
|
591
|
-
const isQuarantined = this.
|
|
599
|
+
const { isDisabled, isQuarantined } = this.getTestProperties(spec.relative, cypressTestName)
|
|
592
600
|
|
|
593
|
-
if (
|
|
601
|
+
if (isDisabled) {
|
|
602
|
+
skippedTestSpan.setTag(TEST_MANAGEMENT_IS_DISABLED, 'true')
|
|
603
|
+
} else if (isQuarantined) {
|
|
594
604
|
skippedTestSpan.setTag(TEST_MANAGEMENT_IS_QUARANTINED, 'true')
|
|
595
605
|
}
|
|
596
606
|
|
|
@@ -697,7 +707,7 @@ class CypressPlugin {
|
|
|
697
707
|
})
|
|
698
708
|
const isUnskippable = this.unskippableSuites.includes(testSuite)
|
|
699
709
|
const isForcedToRun = shouldSkip && isUnskippable
|
|
700
|
-
const isQuarantined = this.
|
|
710
|
+
const { isDisabled, isQuarantined } = this.getTestProperties(testSuite, testName)
|
|
701
711
|
|
|
702
712
|
// skip test
|
|
703
713
|
if (shouldSkip && !isUnskippable) {
|
|
@@ -708,7 +718,7 @@ class CypressPlugin {
|
|
|
708
718
|
|
|
709
719
|
// TODO: I haven't found a way to trick cypress into ignoring a test
|
|
710
720
|
// The way we'll implement quarantine in cypress is by skipping the test altogether
|
|
711
|
-
if (isQuarantined) {
|
|
721
|
+
if (isDisabled || isQuarantined) {
|
|
712
722
|
return { shouldSkip: true }
|
|
713
723
|
}
|
|
714
724
|
|
|
@@ -737,8 +747,7 @@ class CypressPlugin {
|
|
|
737
747
|
testSuiteAbsolutePath,
|
|
738
748
|
testName,
|
|
739
749
|
isNew,
|
|
740
|
-
isEfdRetry
|
|
741
|
-
isQuarantined
|
|
750
|
+
isEfdRetry
|
|
742
751
|
} = test
|
|
743
752
|
if (coverage && this.isCodeCoverageEnabled && this.tracer._tracer._exporter?.exportCoverage) {
|
|
744
753
|
const coverageFiles = getCoveredFilenamesFromCoverage(coverage)
|
|
@@ -777,9 +786,6 @@ class CypressPlugin {
|
|
|
777
786
|
this.activeTestSpan.setTag(TEST_RETRY_REASON, 'efd')
|
|
778
787
|
}
|
|
779
788
|
}
|
|
780
|
-
if (isQuarantined) {
|
|
781
|
-
this.activeTestSpan.setTag(TEST_MANAGEMENT_IS_QUARANTINED, 'true')
|
|
782
|
-
}
|
|
783
789
|
const finishedTest = {
|
|
784
790
|
testName,
|
|
785
791
|
testStatus,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const NoopTracer = require('../../dd-trace/src/noop/tracer')
|
|
2
2
|
const cypressPlugin = require('./cypress-plugin')
|
|
3
|
+
const satisfies = require('semifies')
|
|
3
4
|
|
|
4
5
|
const noopTask = {
|
|
5
6
|
'dd:testSuiteStart': () => {
|
|
@@ -19,6 +20,15 @@ const noopTask = {
|
|
|
19
20
|
module.exports = (on, config) => {
|
|
20
21
|
const tracer = require('../../dd-trace')
|
|
21
22
|
|
|
23
|
+
if (satisfies(config.version, '<10.2.0')) {
|
|
24
|
+
// console.warn does not seem to work in cypress, so using console.log instead
|
|
25
|
+
// eslint-disable-next-line no-console
|
|
26
|
+
console.log(
|
|
27
|
+
'WARNING: dd-trace support for Cypress<10.2.0 is deprecated' +
|
|
28
|
+
' and will not be supported in future versions of dd-trace.'
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
// The tracer was not init correctly for whatever reason (such as invalid DD_SITE)
|
|
23
33
|
if (tracer._tracer instanceof NoopTracer) {
|
|
24
34
|
// We still need to register these tasks or the support file will fail
|