dd-trace 6.10.0 → 6.12.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 +5 -0
- package/README.md +0 -17
- package/index.d.ts +128 -6
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +27 -23
- package/packages/datadog-esbuild/index.js +0 -34
- package/packages/datadog-instrumentations/src/anthropic.js +210 -15
- package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
- package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +3 -16
- package/packages/datadog-instrumentations/src/cucumber.js +30 -15
- package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
- package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
- package/packages/datadog-instrumentations/src/cypress.js +2 -0
- package/packages/datadog-instrumentations/src/fastify.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
- package/packages/datadog-instrumentations/src/jest.js +25 -17
- package/packages/datadog-instrumentations/src/mariadb.js +278 -21
- package/packages/datadog-instrumentations/src/mocha/main.js +539 -55
- package/packages/datadog-instrumentations/src/mocha/utils.js +135 -19
- package/packages/datadog-instrumentations/src/playwright-reporter.js +247 -0
- package/packages/datadog-instrumentations/src/playwright.js +182 -35
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +6 -8
- package/packages/datadog-instrumentations/src/vitest-main.js +11 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -8
- package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
- package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
- package/packages/datadog-plugin-bunyan/src/index.js +5 -8
- package/packages/datadog-plugin-cucumber/src/index.js +11 -0
- package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
- package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +81 -29
- package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
- package/packages/datadog-plugin-cypress/src/index.js +12 -6
- package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
- package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
- package/packages/datadog-plugin-electron/src/index.js +2 -0
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +6 -0
- package/packages/datadog-plugin-mocha/src/index.js +56 -1
- package/packages/datadog-plugin-nats/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +41 -30
- package/packages/datadog-plugin-openai-agents/src/integration.js +1 -0
- package/packages/datadog-plugin-playwright/src/index.js +46 -13
- package/packages/datadog-plugin-vitest/src/index.js +6 -0
- package/packages/datadog-webpack/index.js +0 -11
- package/packages/dd-trace/index.js +0 -1
- package/packages/dd-trace/src/agent/info.js +6 -5
- package/packages/dd-trace/src/aiguard/client.js +100 -1
- package/packages/dd-trace/src/aiguard/errors.js +41 -0
- package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
- package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
- package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
- package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
- package/packages/dd-trace/src/aiguard/sdk.js +22 -278
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
- package/packages/dd-trace/src/appsec/reporter.js +2 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +13 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +24 -0
- package/packages/dd-trace/src/carrier.js +107 -48
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +29 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +27 -9
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +26 -8
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +10 -4
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +13 -2
- package/packages/dd-trace/src/config/major-overrides.js +7 -0
- package/packages/dd-trace/src/config/supported-configurations.json +14 -0
- package/packages/dd-trace/src/datastreams/index.js +2 -0
- package/packages/dd-trace/src/datastreams/manager.js +9 -2
- package/packages/dd-trace/src/datastreams/processor.js +15 -13
- package/packages/dd-trace/src/datastreams/size.js +5 -0
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +5 -11
- package/packages/dd-trace/src/debugger/index.js +4 -2
- package/packages/dd-trace/src/debugger/inspect-segment.js +154 -0
- package/packages/dd-trace/src/evp_proxy/constants.js +8 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +64 -0
- package/packages/dd-trace/src/evp_proxy/discovery.js +133 -0
- package/packages/dd-trace/src/evp_proxy/path.js +22 -0
- package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
- package/packages/dd-trace/src/exporters/common/request.js +5 -2
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/experiments/client.js +167 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +484 -92
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +302 -29
- package/packages/dd-trace/src/llmobs/experiments/index.js +75 -64
- package/packages/dd-trace/src/llmobs/experiments/noop.js +135 -7
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +101 -9
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
- package/packages/dd-trace/src/noop/proxy.js +3 -4
- package/packages/dd-trace/src/openfeature/constants/constants.js +0 -18
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/index.js +7 -4
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/base.js +153 -11
- package/packages/dd-trace/src/openfeature/writers/exposures.js +62 -14
- package/packages/dd-trace/src/openfeature/writers/util.js +97 -15
- package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +22 -13
- package/packages/dd-trace/src/opentracing/tracer.js +5 -2
- package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
- package/packages/dd-trace/src/plugin_manager.js +3 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/jest.js +4 -3
- package/packages/dd-trace/src/plugins/util/test.js +9 -9
- package/packages/dd-trace/src/plugins/util/web.js +3 -0
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
- package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
- package/packages/dd-trace/src/proxy.js +38 -29
- package/packages/dd-trace/src/ritm.js +9 -2
- package/packages/dd-trace/src/serverless.js +37 -0
- package/packages/dd-trace/src/span_format.js +1 -0
- package/packages/dd-trace/src/span_stats.js +30 -3
- package/packages/dd-trace/src/storage-channels.js +86 -0
- package/packages/dd-trace/src/telemetry/metrics.js +62 -8
- package/packages/dd-trace/src/telemetry/send-data.js +1 -0
- package/packages/dd-trace/src/tracer.js +9 -2
- package/packages/dd-trace/src/tracer_metadata.js +14 -1
- package/packages/dd-trace/src/web-tags-cache.js +132 -0
- package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/https-proxy-agent/LICENSE +22 -0
- package/vendor/dist/https-proxy-agent/index.js +4 -0
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/proxy-from-env/LICENSE +20 -0
- package/vendor/dist/proxy-from-env/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
- package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
- package/packages/dd-trace/src/feature-registry.js +0 -29
- package/packages/dd-trace/src/openfeature/register.js +0 -35
- package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
|
@@ -45,6 +45,9 @@ const testSkipCh = channel('ci:playwright:test:skip')
|
|
|
45
45
|
const testSessionStartCh = channel('ci:playwright:session:start')
|
|
46
46
|
const testSessionConfigurationCh = channel('ci:playwright:session:configuration')
|
|
47
47
|
const testSessionFinishCh = channel('ci:playwright:session:finish')
|
|
48
|
+
const reporterErrorCh = channel('ci:playwright:reporter:error')
|
|
49
|
+
const reporterRunSummaryCh = channel('ci:playwright:reporter:run-summary')
|
|
50
|
+
const reporterSuiteHookErrorCh = channel('ci:playwright:reporter:suite-hook-error')
|
|
48
51
|
|
|
49
52
|
const libraryConfigurationCh = channel('ci:playwright:library-configuration')
|
|
50
53
|
const knownTestsCh = channel('ci:playwright:known-tests')
|
|
@@ -81,6 +84,8 @@ const isFailureScreenshotUploadEnabled =
|
|
|
81
84
|
getValueFromEnvSources('DD_TEST_FAILURE_SCREENSHOTS_ENABLED') === true
|
|
82
85
|
|
|
83
86
|
let applyRepeatEachIndex = null
|
|
87
|
+
let reporterError
|
|
88
|
+
let hasReporterError = false
|
|
84
89
|
|
|
85
90
|
let startedSuites = []
|
|
86
91
|
|
|
@@ -108,7 +113,7 @@ let testManagementAttemptToFixRetries = 0
|
|
|
108
113
|
let testManagementTests = {}
|
|
109
114
|
let isImpactedTestsEnabled = false
|
|
110
115
|
let modifiedFiles = {}
|
|
111
|
-
let
|
|
116
|
+
let playwrightRunSummary
|
|
112
117
|
let recordedTestOptimizationExecutions = new Set()
|
|
113
118
|
let testsReportedInGenerateSummary = new Set()
|
|
114
119
|
const newTestsWithDynamicNames = new Set()
|
|
@@ -134,8 +139,10 @@ const DD_PROPERTIES_REQUEST = 'ddPropertiesRequest'
|
|
|
134
139
|
const DD_PROPERTIES_RESPONSE = 'ddProperties'
|
|
135
140
|
const kDdPlaywrightDisabledTestIds = Symbol('ddPlaywrightDisabledTestIds')
|
|
136
141
|
const kDdPlaywrightFailureScreenshots = Symbol('ddPlaywrightFailureScreenshots')
|
|
142
|
+
const kDdPlaywrightReporterConfigured = Symbol('ddPlaywrightReporterConfigured')
|
|
137
143
|
const kDdPlaywrightWorkerHostInstrumented = Symbol('ddPlaywrightWorkerHostInstrumented')
|
|
138
144
|
const kDdPlaywrightWorkerInstrumented = Symbol('ddPlaywrightWorkerInstrumented')
|
|
145
|
+
const instrumentedPlaywrightReporters = new WeakSet()
|
|
139
146
|
const PLAYWRIGHT_FAILURE_SCREENSHOT_PATH_RE = /(?:^|[\\/])test-failed-\d+\.png$/
|
|
140
147
|
const automaticFailureScreenshotPaths = new Set()
|
|
141
148
|
|
|
@@ -780,6 +787,7 @@ function finishTestSuiteIfDone (testSuiteAbsolutePath, projects) {
|
|
|
780
787
|
testSourceLine: test.location.line,
|
|
781
788
|
browserName,
|
|
782
789
|
isNew: test._ddIsNew,
|
|
790
|
+
isAttemptToFix: test._ddIsAttemptToFix,
|
|
783
791
|
isDisabled: test._ddIsDisabled,
|
|
784
792
|
isModified: test._ddIsModified,
|
|
785
793
|
isQuarantined: test._ddIsQuarantined,
|
|
@@ -827,6 +835,7 @@ function testEndHandler ({
|
|
|
827
835
|
|
|
828
836
|
if (hookError) {
|
|
829
837
|
addErrorToTestSuite(testSuiteAbsolutePath, hookError)
|
|
838
|
+
reporterSuiteHookErrorCh.publish(testSuiteAbsolutePath)
|
|
830
839
|
}
|
|
831
840
|
return
|
|
832
841
|
}
|
|
@@ -912,9 +921,7 @@ function testEndHandler ({
|
|
|
912
921
|
|
|
913
922
|
// Check if all EFD retries failed
|
|
914
923
|
const efdRetryCount = getEfdRetryCountForTest(test)
|
|
915
|
-
if (efdRetryCount > 0 && testStatuses.length === efdRetryCount + 1 &&
|
|
916
|
-
(test._ddIsNew || test._ddIsModified) &&
|
|
917
|
-
isEarlyFlakeDetectionEnabled &&
|
|
924
|
+
if (isEfdManagedTest && efdRetryCount > 0 && testStatuses.length === efdRetryCount + 1 &&
|
|
918
925
|
testStatuses.every(status => status === 'fail')) {
|
|
919
926
|
test._ddHasFailedAllRetries = true
|
|
920
927
|
}
|
|
@@ -1252,6 +1259,18 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
|
|
|
1252
1259
|
function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
1253
1260
|
// Config parameter is only available from >=1.55.0
|
|
1254
1261
|
return async function (config) {
|
|
1262
|
+
reporterError = undefined
|
|
1263
|
+
hasReporterError = false
|
|
1264
|
+
playwrightRunSummary = undefined
|
|
1265
|
+
let restoreReporterConsoleError
|
|
1266
|
+
if (satisfies(playwrightVersion, '>=1.60.0') && config?.config) {
|
|
1267
|
+
const DatadogPlaywrightReporter = require('./playwright-reporter')
|
|
1268
|
+
restoreReporterConsoleError = DatadogPlaywrightReporter.restoreConsoleError
|
|
1269
|
+
if (!config.config[kDdPlaywrightReporterConfigured]) {
|
|
1270
|
+
Object.defineProperty(config.config, kDdPlaywrightReporterConfigured, { value: true })
|
|
1271
|
+
config.config.reporter.unshift([require.resolve('./playwright-reporter')])
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1255
1274
|
rootDir = getRootDir(this, config)
|
|
1256
1275
|
const projects = getProjectsFromRunner(this, config)
|
|
1257
1276
|
const isFailureScreenshotEnabled = isFailureScreenshotCaptureEnabled(projects)
|
|
@@ -1367,7 +1386,27 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1367
1386
|
}
|
|
1368
1387
|
}
|
|
1369
1388
|
|
|
1370
|
-
let runAllTestsReturn
|
|
1389
|
+
let runAllTestsReturn
|
|
1390
|
+
try {
|
|
1391
|
+
runAllTestsReturn = await runAllTests.apply(this, arguments)
|
|
1392
|
+
} catch (error) {
|
|
1393
|
+
try {
|
|
1394
|
+
await getChannelPromise(testSessionFinishCh, {
|
|
1395
|
+
status: 'fail',
|
|
1396
|
+
error: hasReporterError ? reporterError : error,
|
|
1397
|
+
isEarlyFlakeDetectionEnabled,
|
|
1398
|
+
isEarlyFlakeDetectionFaulty,
|
|
1399
|
+
isTestManagementTestsEnabled,
|
|
1400
|
+
})
|
|
1401
|
+
} catch (finalizationError) {
|
|
1402
|
+
log.error('Playwright test session finalization error: %s', finalizationError)
|
|
1403
|
+
}
|
|
1404
|
+
reporterError = undefined
|
|
1405
|
+
hasReporterError = false
|
|
1406
|
+
throw error
|
|
1407
|
+
} finally {
|
|
1408
|
+
restoreReporterConsoleError?.()
|
|
1409
|
+
}
|
|
1371
1410
|
|
|
1372
1411
|
// Tests that have only skipped tests may reach this point
|
|
1373
1412
|
// Skipped tests may or may not go through `testBegin` or `testEnd`
|
|
@@ -1397,23 +1436,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1397
1436
|
const sessionStatus = runAllTestsReturn.status || runAllTestsReturn
|
|
1398
1437
|
|
|
1399
1438
|
if (isTestManagementTestsEnabled && sessionStatus === 'failed') {
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
for (const [fqn, testStatuses] of testsToTestStatuses) {
|
|
1404
|
-
// Only count as failed if the final status (after retries) is 'fail'
|
|
1405
|
-
const lastStatus = testStatuses.at(-1)
|
|
1406
|
-
if (lastStatus === 'fail') {
|
|
1407
|
-
totalFailedTestCount += 1
|
|
1408
|
-
if (quarantinedButNotAttemptToFixFqns.has(fqn)) {
|
|
1409
|
-
totalPureQuarantinedFailedTestCount += 1
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
const totalIgnorableFailures = totalPureQuarantinedFailedTestCount
|
|
1415
|
-
|
|
1416
|
-
if (totalFailedTestCount > 0 && totalFailedTestCount === totalIgnorableFailures) {
|
|
1439
|
+
const { failureCount, quarantinedFailureCount, hasIncompleteTests } = playwrightRunSummary || {}
|
|
1440
|
+
if (!hasIncompleteTests && quarantinedFailureCount > 0 && quarantinedFailureCount === failureCount) {
|
|
1417
1441
|
runAllTestsReturn = 'passed'
|
|
1418
1442
|
preventedToFail = true
|
|
1419
1443
|
}
|
|
@@ -1422,16 +1446,25 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1422
1446
|
logTestOptimizationSummary({ attemptToFixExecutions, newTestsWithDynamicNames })
|
|
1423
1447
|
loggedAttemptToFixTests.clear()
|
|
1424
1448
|
|
|
1449
|
+
const finalizationError = reporterError
|
|
1450
|
+
const finalStatus = hasReporterError
|
|
1451
|
+
? 'fail'
|
|
1452
|
+
: (preventedToFail ? 'pass' : STATUS_TO_TEST_STATUS[sessionStatus])
|
|
1425
1453
|
await getChannelPromise(testSessionFinishCh, {
|
|
1426
|
-
status:
|
|
1454
|
+
status: finalStatus,
|
|
1455
|
+
error: finalizationError,
|
|
1427
1456
|
isEarlyFlakeDetectionEnabled,
|
|
1428
1457
|
isEarlyFlakeDetectionFaulty,
|
|
1429
1458
|
isTestManagementTestsEnabled,
|
|
1430
1459
|
})
|
|
1460
|
+
if (hasReporterError) {
|
|
1461
|
+
if (typeof runAllTestsReturn === 'string') runAllTestsReturn = 'failed'
|
|
1462
|
+
else runAllTestsReturn.status = 'failed'
|
|
1463
|
+
}
|
|
1431
1464
|
|
|
1432
1465
|
startedSuites = []
|
|
1433
1466
|
remainingTestsByFile = {}
|
|
1434
|
-
|
|
1467
|
+
playwrightRunSummary = undefined
|
|
1435
1468
|
recordedTestOptimizationExecutions = new Set()
|
|
1436
1469
|
testsReportedInGenerateSummary = new Set()
|
|
1437
1470
|
efdManagedTestKeys.clear()
|
|
@@ -1444,6 +1477,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1444
1477
|
ddPropertiesByTestId.clear()
|
|
1445
1478
|
ddPropertiesRequestsByTestId.clear()
|
|
1446
1479
|
disabledTestIds.clear()
|
|
1480
|
+
reporterError = undefined
|
|
1481
|
+
hasReporterError = false
|
|
1447
1482
|
|
|
1448
1483
|
// TODO: we can trick playwright into thinking the session passed by returning
|
|
1449
1484
|
// 'passed' here. We might be able to use this for both EFD and Test Management tests.
|
|
@@ -1451,6 +1486,70 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1451
1486
|
}
|
|
1452
1487
|
}
|
|
1453
1488
|
|
|
1489
|
+
/**
|
|
1490
|
+
* Records errors thrown or rejected by Playwright reporters before Playwright converts them into run status.
|
|
1491
|
+
*
|
|
1492
|
+
* @param {object} reportersPackage
|
|
1493
|
+
* @returns {object}
|
|
1494
|
+
*/
|
|
1495
|
+
function reportersHook (reportersPackage) {
|
|
1496
|
+
return shimmer.wrap(reportersPackage, 'createReporters', createReporters => async function () {
|
|
1497
|
+
const reporters = await createReporters.apply(this, arguments)
|
|
1498
|
+
const DatadogPlaywrightReporter = require('./playwright-reporter')
|
|
1499
|
+
reporters.unshift(new DatadogPlaywrightReporter({ captureReporterErrors: false }))
|
|
1500
|
+
for (const reporter of reporters) {
|
|
1501
|
+
if (instrumentedPlaywrightReporters.has(reporter)) continue
|
|
1502
|
+
|
|
1503
|
+
const onEnd = reporter.onEnd
|
|
1504
|
+
const onExit = reporter.onExit
|
|
1505
|
+
try {
|
|
1506
|
+
if (typeof onEnd === 'function') {
|
|
1507
|
+
reporter.onEnd = async function () {
|
|
1508
|
+
try {
|
|
1509
|
+
return await onEnd.apply(this, arguments)
|
|
1510
|
+
} catch (error) {
|
|
1511
|
+
recordReporterError(error)
|
|
1512
|
+
throw error
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
if (typeof onExit === 'function') {
|
|
1517
|
+
reporter.onExit = async function () {
|
|
1518
|
+
try {
|
|
1519
|
+
return await onExit.apply(this, arguments)
|
|
1520
|
+
} catch (error) {
|
|
1521
|
+
recordReporterError(error)
|
|
1522
|
+
throw error
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
} catch {
|
|
1527
|
+
continue
|
|
1528
|
+
}
|
|
1529
|
+
if (reporter.onEnd !== onEnd || reporter.onExit !== onExit) instrumentedPlaywrightReporters.add(reporter)
|
|
1530
|
+
}
|
|
1531
|
+
return reporters
|
|
1532
|
+
}, { replaceGetter: true })
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
/**
|
|
1536
|
+
* Records errors from the reporter multiplexer used by Playwright before 1.38.
|
|
1537
|
+
*
|
|
1538
|
+
* @param {object} reportersPackage
|
|
1539
|
+
* @returns {object}
|
|
1540
|
+
*/
|
|
1541
|
+
function reporterMultiplexerHook (reportersPackage) {
|
|
1542
|
+
shimmer.wrap(reportersPackage.Multiplexer.prototype, 'onEnd', onEnd => async function () {
|
|
1543
|
+
try {
|
|
1544
|
+
return await onEnd.apply(this, arguments)
|
|
1545
|
+
} catch (error) {
|
|
1546
|
+
recordReporterError(error)
|
|
1547
|
+
throw error
|
|
1548
|
+
}
|
|
1549
|
+
})
|
|
1550
|
+
return reportersPackage
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1454
1553
|
function runnerHook (runnerExport, playwrightVersion) {
|
|
1455
1554
|
shimmer.wrap(
|
|
1456
1555
|
runnerExport.Runner.prototype,
|
|
@@ -1550,6 +1649,36 @@ pageGotoCh.subscribe({
|
|
|
1550
1649
|
},
|
|
1551
1650
|
})
|
|
1552
1651
|
|
|
1652
|
+
reporterErrorCh.subscribe((error) => {
|
|
1653
|
+
recordReporterError(error)
|
|
1654
|
+
})
|
|
1655
|
+
|
|
1656
|
+
reporterRunSummaryCh.subscribe((runSummary) => {
|
|
1657
|
+
playwrightRunSummary = runSummary
|
|
1658
|
+
})
|
|
1659
|
+
|
|
1660
|
+
/**
|
|
1661
|
+
* Records a reporter failure even when the reporter throws a falsy value.
|
|
1662
|
+
*
|
|
1663
|
+
* @param {unknown} error
|
|
1664
|
+
* @returns {void}
|
|
1665
|
+
*/
|
|
1666
|
+
function recordReporterError (error) {
|
|
1667
|
+
if (hasReporterError) return
|
|
1668
|
+
|
|
1669
|
+
let normalizedError
|
|
1670
|
+
try {
|
|
1671
|
+
const errorObject = error && typeof error === 'object' ? error : undefined
|
|
1672
|
+
normalizedError = new Error(errorObject?.message || errorObject?.value || String(error))
|
|
1673
|
+
normalizedError.name = errorObject?.name || normalizedError.name
|
|
1674
|
+
normalizedError.stack = errorObject?.stack || normalizedError.stack
|
|
1675
|
+
} catch {
|
|
1676
|
+
normalizedError = new Error('Playwright reporter failed')
|
|
1677
|
+
}
|
|
1678
|
+
reporterError = normalizedError
|
|
1679
|
+
hasReporterError = true
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1553
1682
|
/**
|
|
1554
1683
|
* Records a path created by Playwright's automatic screenshot recorder.
|
|
1555
1684
|
*
|
|
@@ -1597,6 +1726,12 @@ if (DD_MAJOR < 6) { // <1.38.0 is only supported up to version 5
|
|
|
1597
1726
|
file: 'lib/runner/runner.js',
|
|
1598
1727
|
versions: ['>=1.31.0 <1.38.0'],
|
|
1599
1728
|
}, runnerHook)
|
|
1729
|
+
|
|
1730
|
+
addHook({
|
|
1731
|
+
name: '@playwright/test',
|
|
1732
|
+
file: 'lib/reporters/multiplexer.js',
|
|
1733
|
+
versions: ['>=1.18.0 <1.38.0'],
|
|
1734
|
+
}, reporterMultiplexerHook)
|
|
1600
1735
|
}
|
|
1601
1736
|
|
|
1602
1737
|
addHook({
|
|
@@ -1617,6 +1752,12 @@ addHook({
|
|
|
1617
1752
|
versions: ['>=1.38.0 <1.60.0'],
|
|
1618
1753
|
}, runnerHook)
|
|
1619
1754
|
|
|
1755
|
+
addHook({
|
|
1756
|
+
name: 'playwright',
|
|
1757
|
+
file: 'lib/runner/reporters.js',
|
|
1758
|
+
versions: ['>=1.38.0 <1.60.0'],
|
|
1759
|
+
}, reportersHook)
|
|
1760
|
+
|
|
1620
1761
|
addHook({
|
|
1621
1762
|
name: 'playwright',
|
|
1622
1763
|
file: 'lib/runner/testRunner.js',
|
|
@@ -1747,11 +1888,6 @@ function processRootSuite (createRootSuiteReturnValue) {
|
|
|
1747
1888
|
}
|
|
1748
1889
|
if (testProperties.quarantined) {
|
|
1749
1890
|
test._ddIsQuarantined = true
|
|
1750
|
-
if (!testProperties.attemptToFix) {
|
|
1751
|
-
// Do not skip quarantined tests, let them run and overwrite results post-run if they fail
|
|
1752
|
-
const testFqn = getTestFullyQualifiedName(test)
|
|
1753
|
-
quarantinedButNotAttemptToFixFqns.add(testFqn)
|
|
1754
|
-
}
|
|
1755
1891
|
}
|
|
1756
1892
|
if (testProperties.attemptToFix) {
|
|
1757
1893
|
test._ddIsAttemptToFix = true
|
|
@@ -1791,7 +1927,10 @@ function processRootSuite (createRootSuiteReturnValue) {
|
|
|
1791
1927
|
const fileSuitesWithImpactedTestsToProjects = new Map()
|
|
1792
1928
|
for (const impactedTest of impactedTests) {
|
|
1793
1929
|
impactedTest._ddIsModified = true
|
|
1794
|
-
if (shouldRunEarlyFlakeDetection() && impactedTest.expectedStatus !== 'skipped'
|
|
1930
|
+
if (shouldRunEarlyFlakeDetection() && impactedTest.expectedStatus !== 'skipped' &&
|
|
1931
|
+
!impactedTest._ddIsAttemptToFix) {
|
|
1932
|
+
// Prevent ATR or `--retries` from retrying tests that EFD manages.
|
|
1933
|
+
impactedTest.retries = 0
|
|
1795
1934
|
markEfdManagedTest(impactedTest)
|
|
1796
1935
|
const fileSuite = getSuiteType(impactedTest, 'file')
|
|
1797
1936
|
if (!fileSuitesWithImpactedTestsToProjects.has(fileSuite)) {
|
|
@@ -1799,14 +1938,15 @@ function processRootSuite (createRootSuiteReturnValue) {
|
|
|
1799
1938
|
}
|
|
1800
1939
|
}
|
|
1801
1940
|
}
|
|
1802
|
-
// If something
|
|
1941
|
+
// If something changes in the file, all tests in the file are impacted, except attempt-to-fix tests managed above.
|
|
1803
1942
|
applyRetriesToTests(
|
|
1804
1943
|
fileSuitesWithImpactedTestsToProjects,
|
|
1805
|
-
() =>
|
|
1944
|
+
(test) => !test._ddIsAttemptToFix,
|
|
1806
1945
|
[
|
|
1807
1946
|
'_ddIsModified',
|
|
1808
1947
|
'_ddIsEfdRetry',
|
|
1809
1948
|
(test) => (isKnownTestsEnabled && isNewTest(test) ? '_ddIsNew' : null),
|
|
1949
|
+
(test) => test._ddIsQuarantined && '_ddIsQuarantined',
|
|
1810
1950
|
],
|
|
1811
1951
|
earlyFlakeDetectionRetryPolicy.schedulingRetryCount,
|
|
1812
1952
|
(copiedTest, originalTest, retryIndex) => {
|
|
@@ -1834,7 +1974,8 @@ function processRootSuite (createRootSuiteReturnValue) {
|
|
|
1834
1974
|
const fileSuitesWithNewTestsToProjects = new Map()
|
|
1835
1975
|
for (const newTest of newTests) {
|
|
1836
1976
|
newTest._ddIsNew = true
|
|
1837
|
-
if (shouldRunEarlyFlakeDetection() && newTest.expectedStatus !== 'skipped' &&
|
|
1977
|
+
if (shouldRunEarlyFlakeDetection() && newTest.expectedStatus !== 'skipped' &&
|
|
1978
|
+
!newTest._ddIsModified && !newTest._ddIsAttemptToFix) {
|
|
1838
1979
|
// Prevent ATR or `--retries` from retrying tests that EFD manages.
|
|
1839
1980
|
newTest.retries = 0
|
|
1840
1981
|
markEfdManagedTest(newTest)
|
|
@@ -1847,8 +1988,12 @@ function processRootSuite (createRootSuiteReturnValue) {
|
|
|
1847
1988
|
|
|
1848
1989
|
applyRetriesToTests(
|
|
1849
1990
|
fileSuitesWithNewTestsToProjects,
|
|
1850
|
-
isNewTest,
|
|
1851
|
-
[
|
|
1991
|
+
(test) => !test._ddIsAttemptToFix && isNewTest(test),
|
|
1992
|
+
[
|
|
1993
|
+
'_ddIsNew',
|
|
1994
|
+
'_ddIsEfdRetry',
|
|
1995
|
+
(test) => test._ddIsQuarantined && '_ddIsQuarantined',
|
|
1996
|
+
],
|
|
1852
1997
|
earlyFlakeDetectionRetryPolicy.schedulingRetryCount,
|
|
1853
1998
|
(copiedTest, originalTest, retryIndex) => {
|
|
1854
1999
|
markEfdRetryTest(copiedTest, retryIndex, originalTest)
|
|
@@ -2300,6 +2445,7 @@ function generateSummaryWrapper (generateSummary) {
|
|
|
2300
2445
|
line: testSourceLine,
|
|
2301
2446
|
},
|
|
2302
2447
|
_ddIsNew: isNew,
|
|
2448
|
+
_ddIsAttemptToFix: isAttemptToFix,
|
|
2303
2449
|
_ddIsDisabled: isDisabled,
|
|
2304
2450
|
_ddIsModified: isModified,
|
|
2305
2451
|
_ddIsQuarantined: isQuarantined,
|
|
@@ -2314,6 +2460,7 @@ function generateSummaryWrapper (generateSummary) {
|
|
|
2314
2460
|
testSourceLine,
|
|
2315
2461
|
browserName,
|
|
2316
2462
|
isNew,
|
|
2463
|
+
isAttemptToFix,
|
|
2317
2464
|
isDisabled,
|
|
2318
2465
|
isModified,
|
|
2319
2466
|
isQuarantined,
|
|
@@ -596,6 +596,7 @@ const visitedParams = new WeakSet()
|
|
|
596
596
|
function wrapHandleRequest (original) {
|
|
597
597
|
return function wrappedHandleRequest (...args) {
|
|
598
598
|
const req = args[0]
|
|
599
|
+
// eslint-disable-next-line no-restricted-syntax -- arbitrary param names; publishing {} sets a WAF address
|
|
599
600
|
if (routerParamStartCh.hasSubscribers && !visitedParams.has(req.params) && Object.keys(req.params).length) {
|
|
600
601
|
visitedParams.add(req.params)
|
|
601
602
|
|
|
@@ -635,6 +636,7 @@ function wrapParam (original) {
|
|
|
635
636
|
args[1] = shimmer.wrapFunction(args[1], (originalFn) => {
|
|
636
637
|
return function wrappedFn (...fnArgs) {
|
|
637
638
|
const req = fnArgs[0]
|
|
639
|
+
// eslint-disable-next-line no-restricted-syntax -- arbitrary param names; publishing {} sets a WAF address
|
|
638
640
|
if (routerParamStartCh.hasSubscribers && Object.keys(req.params).length && !visitedParams.has(req.params)) {
|
|
639
641
|
visitedParams.add(req.params)
|
|
640
642
|
|
|
@@ -1058,7 +1058,7 @@ function getRepeatedTestReport (task, testName, testSuiteAbsolutePath, testPrope
|
|
|
1058
1058
|
const errors = browserEnvironment
|
|
1059
1059
|
? normalizeVitestBrowserErrors(result?.errors)
|
|
1060
1060
|
: result?.errors || []
|
|
1061
|
-
const finalAttemptStatus = finalStatus(statuses)
|
|
1061
|
+
const finalAttemptStatus = finalStatus(statuses, testProperties)
|
|
1062
1062
|
const hasFailure = finalAttemptStatus === 'fail'
|
|
1063
1063
|
const attempts = []
|
|
1064
1064
|
const attemptCount = getRepeatedAttemptCount(task, statuses)
|
|
@@ -1095,8 +1095,7 @@ function getRepeatedTestReport (task, testName, testSuiteAbsolutePath, testPrope
|
|
|
1095
1095
|
testProperties,
|
|
1096
1096
|
type,
|
|
1097
1097
|
statuses,
|
|
1098
|
-
isFinalAttempt
|
|
1099
|
-
hasFailure
|
|
1098
|
+
isFinalAttempt
|
|
1100
1099
|
),
|
|
1101
1100
|
isRetry: index > 0,
|
|
1102
1101
|
status: attemptStatus,
|
|
@@ -1136,11 +1135,10 @@ function getRepeatedTestReport (task, testName, testSuiteAbsolutePath, testPrope
|
|
|
1136
1135
|
* @param {'attempt_to_fix'|'early_flake_detection'|'external'} type
|
|
1137
1136
|
* @param {string[]} statuses
|
|
1138
1137
|
* @param {boolean} isFinalAttempt
|
|
1139
|
-
* @param {boolean} hasFailure
|
|
1140
1138
|
* @returns {boolean}
|
|
1141
1139
|
*/
|
|
1142
|
-
function hasFailedAllManagedRetries (task, testProperties, type, statuses, isFinalAttempt
|
|
1143
|
-
if (!isFinalAttempt ||
|
|
1140
|
+
function hasFailedAllManagedRetries (task, testProperties, type, statuses, isFinalAttempt) {
|
|
1141
|
+
if (!isFinalAttempt || statuses.length === 0 || !statuses.every(status => status === 'fail')) {
|
|
1144
1142
|
return false
|
|
1145
1143
|
}
|
|
1146
1144
|
|
|
@@ -1165,7 +1163,8 @@ function getAttemptToFixFinalStatus (statuses) {
|
|
|
1165
1163
|
return statuses.includes('fail') ? 'fail' : 'pass'
|
|
1166
1164
|
}
|
|
1167
1165
|
|
|
1168
|
-
function getEarlyFlakeDetectionFinalStatus (statuses) {
|
|
1166
|
+
function getEarlyFlakeDetectionFinalStatus (statuses, testProperties) {
|
|
1167
|
+
if (testProperties.isDisabled || testProperties.isQuarantined) return 'skip'
|
|
1169
1168
|
return statuses.includes('pass') ? 'pass' : 'fail'
|
|
1170
1169
|
}
|
|
1171
1170
|
|
|
@@ -1274,7 +1273,6 @@ function reportFinalTestAttempt (testReport) {
|
|
|
1274
1273
|
testProperties,
|
|
1275
1274
|
'external',
|
|
1276
1275
|
['fail'],
|
|
1277
|
-
true,
|
|
1278
1276
|
true
|
|
1279
1277
|
),
|
|
1280
1278
|
isRetry: (result?.retryCount || 0) > 0 || (result?.repeatCount || 0) > 0,
|
|
@@ -67,6 +67,7 @@ const coverageWrappedProviders = new WeakSet()
|
|
|
67
67
|
const finishWrappedContexts = new WeakSet()
|
|
68
68
|
const runFilesWrappedPrototypes = new WeakSet()
|
|
69
69
|
const activeRunFilesContexts = new WeakSet()
|
|
70
|
+
const runErrorsByContext = new WeakMap()
|
|
70
71
|
let isFlakyTestRetriesEnabled = false
|
|
71
72
|
let flakyTestRetriesCount = 0
|
|
72
73
|
let isEarlyFlakeDetectionEnabled = false
|
|
@@ -1195,15 +1196,18 @@ function getFinishWrapper (exitOrClose) {
|
|
|
1195
1196
|
}
|
|
1196
1197
|
|
|
1197
1198
|
const failedSuites = this.state.getFailedFilepaths()
|
|
1198
|
-
|
|
1199
|
-
|
|
1199
|
+
const runError = runErrorsByContext.get(this)
|
|
1200
|
+
runErrorsByContext.delete(this)
|
|
1201
|
+
let error = runError
|
|
1202
|
+
if (!error && failedSuites.length) {
|
|
1200
1203
|
error = new Error(`Test suites failed: ${failedSuites.length}.`)
|
|
1201
1204
|
}
|
|
1202
1205
|
|
|
1203
1206
|
const flushPromise = getChannelPromise(testSessionFinishCh, {
|
|
1204
|
-
status: areAllSuitesSkipped ? 'skip' : getSessionStatus(this.state),
|
|
1207
|
+
status: runError ? 'fail' : (areAllSuitesSkipped ? 'skip' : getSessionStatus(this.state)),
|
|
1205
1208
|
testCodeCoverageLinesTotal,
|
|
1206
1209
|
error,
|
|
1210
|
+
isTestSessionFinalizationError: Boolean(runError),
|
|
1207
1211
|
isEarlyFlakeDetectionEnabled,
|
|
1208
1212
|
isEarlyFlakeDetectionFaulty,
|
|
1209
1213
|
isTestManagementTestsEnabled,
|
|
@@ -1376,6 +1380,9 @@ function wrapVitestRunFiles (Vitest, frameworkVersion) {
|
|
|
1376
1380
|
activeRunFilesContexts.add(this)
|
|
1377
1381
|
try {
|
|
1378
1382
|
return await runFiles.apply(this, arguments)
|
|
1383
|
+
} catch (error) {
|
|
1384
|
+
runErrorsByContext.set(this, error)
|
|
1385
|
+
throw error
|
|
1379
1386
|
} finally {
|
|
1380
1387
|
activeRunFilesContexts.delete(this)
|
|
1381
1388
|
}
|
|
@@ -1677,6 +1684,7 @@ async function reportTypecheckFile (file, sessionConfiguration, frameworkVersion
|
|
|
1677
1684
|
}
|
|
1678
1685
|
|
|
1679
1686
|
await getChannelPromise(testSuiteFinishCh, {
|
|
1687
|
+
deferFlush: true,
|
|
1680
1688
|
frameworkVersion,
|
|
1681
1689
|
status: getTypecheckTaskStatus(file),
|
|
1682
1690
|
...testSuiteCtx.currentStore,
|