dd-trace 5.41.1 → 5.43.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 +7 -4
- 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 +83 -33
- 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/common.js +2 -1
- 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 +62 -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 +15 -1
- package/packages/dd-trace/src/dogstatsd.js +3 -3
- package/packages/dd-trace/src/encode/0.4.js +108 -12
- package/packages/dd-trace/src/encode/0.5.js +7 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -2
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +3 -2
- package/packages/dd-trace/src/format.js +34 -32
- 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/llmobs/sdk.js +3 -3
- package/packages/dd-trace/src/log/index.js +1 -13
- package/packages/dd-trace/src/log/utils.js +16 -0
- 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/runtime_metrics/runtime_metrics.js +13 -14
- 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
|
}
|
|
@@ -90,6 +94,10 @@ function isReporterPackageNewest (vitestPackage) {
|
|
|
90
94
|
return vitestPackage.h?.name === 'BaseSequencer'
|
|
91
95
|
}
|
|
92
96
|
|
|
97
|
+
function isBaseSequencer (vitestPackage) {
|
|
98
|
+
return vitestPackage.b?.name === 'BaseSequencer'
|
|
99
|
+
}
|
|
100
|
+
|
|
93
101
|
function getChannelPromise (channelToPublishTo) {
|
|
94
102
|
return new Promise(resolve => {
|
|
95
103
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
@@ -167,10 +175,10 @@ function getSortWrapper (sort) {
|
|
|
167
175
|
let earlyFlakeDetectionNumRetries = 0
|
|
168
176
|
let isEarlyFlakeDetectionFaulty = false
|
|
169
177
|
let isKnownTestsEnabled = false
|
|
170
|
-
let
|
|
178
|
+
let isTestManagementTestsEnabled = false
|
|
171
179
|
let isDiEnabled = false
|
|
172
180
|
let knownTests = {}
|
|
173
|
-
let
|
|
181
|
+
let testManagementTests = {}
|
|
174
182
|
|
|
175
183
|
try {
|
|
176
184
|
const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
|
|
@@ -181,7 +189,7 @@ function getSortWrapper (sort) {
|
|
|
181
189
|
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
182
190
|
isDiEnabled = libraryConfig.isDiEnabled
|
|
183
191
|
isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
|
|
184
|
-
|
|
192
|
+
isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
185
193
|
}
|
|
186
194
|
} catch (e) {
|
|
187
195
|
isFlakyTestRetriesEnabled = false
|
|
@@ -192,6 +200,12 @@ function getSortWrapper (sort) {
|
|
|
192
200
|
|
|
193
201
|
if (isFlakyTestRetriesEnabled && !this.ctx.config.retry && flakyTestRetriesCount > 0) {
|
|
194
202
|
this.ctx.config.retry = flakyTestRetriesCount
|
|
203
|
+
try {
|
|
204
|
+
const workspaceProject = this.ctx.getCoreWorkspaceProject()
|
|
205
|
+
workspaceProject._provided._ddIsFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
|
|
206
|
+
} catch (e) {
|
|
207
|
+
log.warn('Could not send library configuration to workers.')
|
|
208
|
+
}
|
|
195
209
|
}
|
|
196
210
|
|
|
197
211
|
if (isKnownTestsEnabled) {
|
|
@@ -241,20 +255,20 @@ function getSortWrapper (sort) {
|
|
|
241
255
|
}
|
|
242
256
|
}
|
|
243
257
|
|
|
244
|
-
if (
|
|
245
|
-
const { err,
|
|
258
|
+
if (isTestManagementTestsEnabled) {
|
|
259
|
+
const { err, testManagementTests: receivedTestManagementTests } = await getChannelPromise(testManagementTestsCh)
|
|
246
260
|
if (!err) {
|
|
247
|
-
|
|
261
|
+
testManagementTests = receivedTestManagementTests
|
|
248
262
|
try {
|
|
249
263
|
const workspaceProject = this.ctx.getCoreWorkspaceProject()
|
|
250
|
-
workspaceProject._provided.
|
|
251
|
-
workspaceProject._provided.
|
|
264
|
+
workspaceProject._provided._ddIsTestManagementTestsEnabled = isTestManagementTestsEnabled
|
|
265
|
+
workspaceProject._provided._ddTestManagementTests = testManagementTests
|
|
252
266
|
} catch (e) {
|
|
253
|
-
log.warn('Could not send
|
|
267
|
+
log.warn('Could not send test management tests to workers so Test Management will not work.')
|
|
254
268
|
}
|
|
255
269
|
} else {
|
|
256
|
-
|
|
257
|
-
log.error('Could not get
|
|
270
|
+
isTestManagementTestsEnabled = false
|
|
271
|
+
log.error('Could not get test management tests.')
|
|
258
272
|
}
|
|
259
273
|
}
|
|
260
274
|
|
|
@@ -292,7 +306,7 @@ function getSortWrapper (sort) {
|
|
|
292
306
|
error,
|
|
293
307
|
isEarlyFlakeDetectionEnabled,
|
|
294
308
|
isEarlyFlakeDetectionFaulty,
|
|
295
|
-
|
|
309
|
+
isTestManagementTestsEnabled,
|
|
296
310
|
onFinish
|
|
297
311
|
})
|
|
298
312
|
})
|
|
@@ -337,9 +351,25 @@ addHook({
|
|
|
337
351
|
knownTests,
|
|
338
352
|
isEarlyFlakeDetectionEnabled,
|
|
339
353
|
isKnownTestsEnabled,
|
|
340
|
-
numRepeats
|
|
354
|
+
numRepeats,
|
|
355
|
+
isTestManagementTestsEnabled,
|
|
356
|
+
testManagementTests
|
|
341
357
|
} = getProvidedContext()
|
|
342
358
|
|
|
359
|
+
if (isTestManagementTestsEnabled) {
|
|
360
|
+
isDisabledCh.publish({
|
|
361
|
+
testManagementTests,
|
|
362
|
+
testSuiteAbsolutePath: task.file.filepath,
|
|
363
|
+
testName,
|
|
364
|
+
onDone: (isTestDisabled) => {
|
|
365
|
+
if (isTestDisabled) {
|
|
366
|
+
disabledTasks.add(task)
|
|
367
|
+
task.mode = 'skip'
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
}
|
|
372
|
+
|
|
343
373
|
if (isKnownTestsEnabled) {
|
|
344
374
|
isNewTestCh.publish({
|
|
345
375
|
knownTests,
|
|
@@ -364,7 +394,7 @@ addHook({
|
|
|
364
394
|
// `onAfterRunTask` is run after all repetitions or attempts are run
|
|
365
395
|
// `onAfterRunTask` is an async function
|
|
366
396
|
shimmer.wrap(VitestTestRunner.prototype, 'onAfterRunTask', onAfterRunTask => function (task) {
|
|
367
|
-
const { isEarlyFlakeDetectionEnabled,
|
|
397
|
+
const { isEarlyFlakeDetectionEnabled, isTestManagementTestsEnabled } = getProvidedContext()
|
|
368
398
|
|
|
369
399
|
if (isEarlyFlakeDetectionEnabled && taskToStatuses.has(task)) {
|
|
370
400
|
const statuses = taskToStatuses.get(task)
|
|
@@ -377,7 +407,7 @@ addHook({
|
|
|
377
407
|
}
|
|
378
408
|
}
|
|
379
409
|
|
|
380
|
-
if (
|
|
410
|
+
if (isTestManagementTestsEnabled) {
|
|
381
411
|
if (quarantinedTasks.has(task)) {
|
|
382
412
|
task.result.state = 'pass'
|
|
383
413
|
}
|
|
@@ -400,17 +430,17 @@ addHook({
|
|
|
400
430
|
isKnownTestsEnabled,
|
|
401
431
|
isEarlyFlakeDetectionEnabled,
|
|
402
432
|
isDiEnabled,
|
|
403
|
-
|
|
404
|
-
|
|
433
|
+
isTestManagementTestsEnabled,
|
|
434
|
+
testManagementTests
|
|
405
435
|
} = getProvidedContext()
|
|
406
436
|
|
|
407
437
|
if (isKnownTestsEnabled) {
|
|
408
438
|
isNew = newTasks.has(task)
|
|
409
439
|
}
|
|
410
440
|
|
|
411
|
-
if (
|
|
441
|
+
if (isTestManagementTestsEnabled) {
|
|
412
442
|
isQuarantinedCh.publish({
|
|
413
|
-
|
|
443
|
+
testManagementTests,
|
|
414
444
|
testSuiteAbsolutePath: task.file.filepath,
|
|
415
445
|
testName,
|
|
416
446
|
onDone: (isTestQuarantined) => {
|
|
@@ -589,11 +619,22 @@ addHook({
|
|
|
589
619
|
|
|
590
620
|
addHook({
|
|
591
621
|
name: 'vitest',
|
|
592
|
-
versions: ['>=3.0.
|
|
622
|
+
versions: ['>=3.0.9'],
|
|
623
|
+
filePattern: 'dist/chunks/coverage.*'
|
|
624
|
+
}, (coveragePackage) => {
|
|
625
|
+
if (isBaseSequencer(coveragePackage)) {
|
|
626
|
+
shimmer.wrap(coveragePackage.b.prototype, 'sort', getSortWrapper)
|
|
627
|
+
}
|
|
628
|
+
return coveragePackage
|
|
629
|
+
})
|
|
630
|
+
|
|
631
|
+
addHook({
|
|
632
|
+
name: 'vitest',
|
|
633
|
+
versions: ['>=3.0.0 <3.0.9'],
|
|
593
634
|
filePattern: 'dist/chunks/resolveConfig.*'
|
|
594
|
-
}, (
|
|
595
|
-
shimmer.wrap(
|
|
596
|
-
return
|
|
635
|
+
}, (resolveConfigPackage) => {
|
|
636
|
+
shimmer.wrap(resolveConfigPackage.B.prototype, 'sort', getSortWrapper)
|
|
637
|
+
return resolveConfigPackage
|
|
597
638
|
})
|
|
598
639
|
|
|
599
640
|
// Can't specify file because compiled vitest includes hashes in their files
|
|
@@ -624,9 +665,16 @@ addHook({
|
|
|
624
665
|
// From >=3.0.1, the first arguments changes from a string to an object containing the filepath
|
|
625
666
|
const testSuiteAbsolutePath = testPaths[0]?.filepath || testPaths[0]
|
|
626
667
|
|
|
668
|
+
const { isEarlyFlakeDetectionEnabled, isFlakyTestRetriesEnabled } = getProvidedContext()
|
|
669
|
+
|
|
627
670
|
const testSuiteAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
628
671
|
testSuiteAsyncResource.runInAsyncScope(() => {
|
|
629
|
-
testSuiteStartCh.publish({
|
|
672
|
+
testSuiteStartCh.publish({
|
|
673
|
+
testSuiteAbsolutePath,
|
|
674
|
+
frameworkVersion,
|
|
675
|
+
isFlakyTestRetriesEnabled,
|
|
676
|
+
isEarlyFlakeDetectionEnabled
|
|
677
|
+
})
|
|
630
678
|
})
|
|
631
679
|
const startTestsResponse = await startTests.apply(this, arguments)
|
|
632
680
|
|
|
@@ -651,7 +699,8 @@ addHook({
|
|
|
651
699
|
testSkipCh.publish({
|
|
652
700
|
testName: getTestName(task),
|
|
653
701
|
testSuiteAbsolutePath: task.file.filepath,
|
|
654
|
-
isNew: newTasks.has(task)
|
|
702
|
+
isNew: newTasks.has(task),
|
|
703
|
+
isDisabled: disabledTasks.has(task)
|
|
655
704
|
})
|
|
656
705
|
} else if (state === 'pass' && !isSwitchedStatus) {
|
|
657
706
|
if (testAsyncResource) {
|
|
@@ -681,7 +730,8 @@ addHook({
|
|
|
681
730
|
testSkipCh.publish({
|
|
682
731
|
testName: getTestName(task),
|
|
683
732
|
testSuiteAbsolutePath: task.file.filepath,
|
|
684
|
-
isNew: newTasks.has(task)
|
|
733
|
+
isNew: newTasks.has(task),
|
|
734
|
+
isDisabled: disabledTasks.has(task)
|
|
685
735
|
})
|
|
686
736
|
}
|
|
687
737
|
})
|
|
@@ -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
|