dd-trace 6.6.0 → 6.8.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/ci/diagnose.js +162 -21
- package/ci/init.js +0 -1
- package/ci/runbook.md +187 -180
- package/ci/test-optimization-validation/approval-artifacts.js +3 -1
- package/ci/test-optimization-validation/approval.js +52 -15
- package/ci/test-optimization-validation/ci-command-candidate.js +26 -32
- package/ci/test-optimization-validation/ci-discovery.js +1 -1
- package/ci/test-optimization-validation/ci-package-scripts.js +141 -0
- package/ci/test-optimization-validation/ci-remediation.js +112 -39
- package/ci/test-optimization-validation/cli.js +516 -681
- package/ci/test-optimization-validation/command-blocker.js +188 -33
- package/ci/test-optimization-validation/command-output-policy.js +8 -31
- package/ci/test-optimization-validation/command-runner.js +189 -245
- package/ci/test-optimization-validation/environment.js +90 -0
- package/ci/test-optimization-validation/executable.js +159 -388
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +119 -0
- package/ci/test-optimization-validation/framework-adapters/cypress.js +107 -0
- package/ci/test-optimization-validation/framework-adapters/playwright.js +181 -0
- package/ci/test-optimization-validation/generated-files.js +84 -22
- package/ci/test-optimization-validation/generated-test-contract.js +281 -0
- package/ci/test-optimization-validation/generated-verifier.js +49 -16
- package/ci/test-optimization-validation/literal-environment.js +57 -0
- package/ci/test-optimization-validation/manifest-loader.js +2 -22
- package/ci/test-optimization-validation/manifest-scaffold.js +815 -515
- package/ci/test-optimization-validation/manifest-schema.js +494 -702
- package/ci/test-optimization-validation/offline-fixtures.js +4 -1
- package/ci/test-optimization-validation/offline-output.js +6 -6
- package/ci/test-optimization-validation/plan-writer.js +243 -984
- package/ci/test-optimization-validation/preflight-runner.js +49 -55
- package/ci/test-optimization-validation/redaction.js +2 -1
- package/ci/test-optimization-validation/report-writer.js +391 -1357
- package/ci/test-optimization-validation/result-semantics.js +86 -0
- package/ci/test-optimization-validation/runner-command.js +249 -0
- package/ci/test-optimization-validation/runner-contract.js +664 -0
- package/ci/test-optimization-validation/safe-files.js +4 -4
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +29 -3
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +240 -543
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +450 -670
- package/ci/test-optimization-validation/scenarios/early-flake-detection.js +4 -3
- package/ci/test-optimization-validation/scenarios/helpers.js +67 -9
- package/ci/test-optimization-validation/scenarios/test-management.js +6 -5
- package/ci/test-optimization-validation/source-text.js +87 -0
- package/ci/test-optimization-validation/test-output.js +12 -22
- package/ci/vitest-no-worker-init-setup.mjs +348 -51
- package/ext/tags.d.ts +1 -0
- package/index.d.ts +84 -13
- package/package.json +10 -4
- package/packages/datadog-core/src/utils/src/kebabcase.js +8 -2
- package/packages/datadog-esbuild/index.js +4 -2
- package/packages/datadog-esbuild/src/utils.js +1 -1
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +4 -4
- package/packages/datadog-instrumentations/src/cucumber.js +9 -6
- package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +10 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +19 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +9 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/openai-agents.js +31 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +57 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +50 -18
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/shared-utils.js +39 -0
- package/packages/datadog-instrumentations/src/http/client.js +1 -3
- package/packages/datadog-instrumentations/src/jest.js +8 -14
- package/packages/datadog-instrumentations/src/mocha/common.js +1 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +2 -42
- package/packages/datadog-instrumentations/src/mocha/utils.js +68 -2
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +19 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +446 -42
- package/packages/datadog-instrumentations/src/moleculer/client.js +1 -1
- package/packages/datadog-instrumentations/src/openai-agents.js +159 -0
- package/packages/datadog-instrumentations/src/playwright.js +3 -2
- package/packages/datadog-instrumentations/src/rhea.js +1 -1
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +525 -56
- package/packages/datadog-instrumentations/src/vitest-main.js +90 -10
- package/packages/datadog-instrumentations/src/webdriverio.js +914 -0
- package/packages/datadog-plugin-aerospike/src/index.js +1 -3
- package/packages/datadog-plugin-amqplib/src/client.js +1 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +2 -2
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -3
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +5 -3
- package/packages/datadog-plugin-bullmq/src/producer.js +3 -3
- package/packages/datadog-plugin-child_process/src/index.js +3 -3
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +5 -8
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -1
- package/packages/datadog-plugin-fastify/src/tracing.js +1 -1
- package/packages/datadog-plugin-fs/src/index.js +0 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +14 -7
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +19 -10
- package/packages/datadog-plugin-graphql/src/execute.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +2 -1
- package/packages/datadog-plugin-jest/src/index.js +2 -3
- package/packages/datadog-plugin-jest/src/util.js +2 -1
- package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +25 -6
- package/packages/datadog-plugin-openai-agents/src/index.js +74 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +503 -0
- package/packages/datadog-plugin-openai-agents/src/processor.js +108 -0
- package/packages/datadog-plugin-openai-agents/src/util.js +60 -0
- package/packages/datadog-plugin-prisma/src/index.js +5 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +16 -13
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-undici/src/index.js +2 -1
- package/packages/datadog-plugin-vitest/src/index.js +84 -11
- package/packages/datadog-webpack/index.js +2 -2
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-base-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/track_event.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +50 -51
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +4 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/webdriverio.js +26 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -1
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +161 -33
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -3
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +7 -5
- package/packages/dd-trace/src/config/defaults.js +14 -6
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -2
- package/packages/dd-trace/src/config/index.js +15 -0
- package/packages/dd-trace/src/config/parsers.js +19 -1
- package/packages/dd-trace/src/config/supported-configurations.json +12 -6
- package/packages/dd-trace/src/datastreams/encoding.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/log.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +1 -4
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +16 -2
- package/packages/dd-trace/src/encode/span-stats.js +7 -1
- package/packages/dd-trace/src/encode/tags-processors.js +2 -2
- package/packages/dd-trace/src/exporter.js +16 -9
- package/packages/dd-trace/src/exporters/common/url.js +3 -5
- package/packages/dd-trace/src/exporters/electron/index.js +4 -1
- package/packages/dd-trace/src/external-logger/src/index.js +1 -2
- package/packages/dd-trace/src/flare/index.js +2 -2
- package/packages/dd-trace/src/id.js +1 -1
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -1
- package/packages/dd-trace/src/llmobs/experiments/client.js +4 -2
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +66 -14
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +289 -95
- package/packages/dd-trace/src/llmobs/experiments/index.js +51 -12
- package/packages/dd-trace/src/llmobs/experiments/noop.js +95 -10
- package/packages/dd-trace/src/llmobs/experiments/result.js +13 -2
- package/packages/dd-trace/src/llmobs/experiments/util.js +218 -0
- package/packages/dd-trace/src/llmobs/index.js +9 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +104 -22
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +5 -9
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +20 -0
- package/packages/dd-trace/src/llmobs/plugins/openai-agents/utils.js +321 -0
- package/packages/dd-trace/src/llmobs/sdk.js +6 -12
- package/packages/dd-trace/src/llmobs/span_processor.js +14 -7
- package/packages/dd-trace/src/llmobs/tagger.js +24 -5
- package/packages/dd-trace/src/llmobs/util.js +56 -3
- package/packages/dd-trace/src/llmobs/writers/spans.js +12 -6
- package/packages/dd-trace/src/noop/proxy.js +2 -2
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +3 -6
- package/packages/dd-trace/src/openfeature/configuration_source.js +5 -8
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +5 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/opentracing/span_context.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +114 -23
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/outbound.js +4 -1
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +7 -6
- package/packages/dd-trace/src/plugins/util/git.js +1 -1
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +2 -2
- package/packages/dd-trace/src/plugins/util/tags.js +2 -0
- package/packages/dd-trace/src/plugins/util/test.js +38 -12
- package/packages/dd-trace/src/plugins/util/url.js +5 -5
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/priority_sampler.js +6 -3
- package/packages/dd-trace/src/profiling/profilers/poisson.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/shared.js +2 -2
- package/packages/dd-trace/src/ritm.js +5 -20
- package/packages/dd-trace/src/span_processor.js +1 -1
- package/packages/dd-trace/src/span_stats.js +22 -4
- package/packages/dd-trace/src/startup-log.js +3 -0
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +3 -1
- package/packages/dd-trace/src/util.js +16 -0
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +12 -12
- package/vendor/dist/pprof-format/index.js +1 -1
- package/vendor/dist/source-map/index.js +1 -1
- package/ci/test-optimization-validation/command-suitability.js +0 -471
- package/ci/test-optimization-validation/init-probe-preload.js +0 -163
- package/ci/test-optimization-validation/init-probe.js +0 -246
- package/ci/test-optimization-validation/late-initialization.js +0 -63
- package/ci/test-optimization-validation/local-command.js +0 -163
- package/ci/test-optimization-validation/setup-runner.js +0 -97
- package/ci/test-optimization-validation-manifest.schema.json +0 -1
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
failWithDebugRerun,
|
|
8
8
|
pass,
|
|
9
9
|
prepareGeneratedScenario,
|
|
10
|
+
reportMissingGeneratedTest,
|
|
10
11
|
requireGeneratedScenario,
|
|
11
12
|
runInstrumentedCommand,
|
|
12
13
|
skip,
|
|
@@ -28,14 +29,14 @@ async function runEarlyFlakeDetection ({ framework, out, options }) {
|
|
|
28
29
|
|
|
29
30
|
const discovery = await discoverScenarioTests({ framework, out, scenarioName, scenario, options })
|
|
30
31
|
if (discovery.tests.length === 0) {
|
|
31
|
-
return
|
|
32
|
+
return reportMissingGeneratedTest({
|
|
32
33
|
command: scenario.runCommand,
|
|
33
34
|
diagnosis: 'The generated new-test candidate was not reported during baseline identity discovery.',
|
|
34
|
-
|
|
35
|
+
discovery,
|
|
35
36
|
framework,
|
|
36
37
|
options,
|
|
37
38
|
out,
|
|
38
|
-
|
|
39
|
+
scenario,
|
|
39
40
|
scenarioName,
|
|
40
41
|
})
|
|
41
42
|
}
|
|
@@ -4,7 +4,7 @@ const fs = require('node:fs')
|
|
|
4
4
|
const path = require('path')
|
|
5
5
|
|
|
6
6
|
const { getArtifactId } = require('../artifact-id')
|
|
7
|
-
const {
|
|
7
|
+
const { buildDatadogEnv, buildOfflineCaptureEnv, runCommand } = require('../command-runner')
|
|
8
8
|
const {
|
|
9
9
|
cleanupGeneratedRuntimeFiles,
|
|
10
10
|
findGeneratedScenario,
|
|
@@ -14,10 +14,10 @@ const {
|
|
|
14
14
|
eventsOfType,
|
|
15
15
|
findTestsByIdentity,
|
|
16
16
|
} = require('../payload-normalizer')
|
|
17
|
-
const { getLocalValidationCommand } = require('../local-command')
|
|
18
17
|
const { cleanupOfflineFixture, createOfflineFixture } = require('../offline-fixtures')
|
|
19
18
|
const { readOfflineOutput } = require('../offline-output')
|
|
20
19
|
const { sanitizeForReport, sanitizeString } = require('../redaction')
|
|
20
|
+
const { getGeneratedCommand } = require('../runner-command')
|
|
21
21
|
const { ensureSafeDirectory, writeFileSafely } = require('../safe-files')
|
|
22
22
|
|
|
23
23
|
const ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}${String.raw`\[[0-?]*[ -/]*[@-~]`}`, 'g')
|
|
@@ -34,7 +34,7 @@ async function runInstrumentedCommand ({
|
|
|
34
34
|
options,
|
|
35
35
|
extraEnv,
|
|
36
36
|
fixtureConfig,
|
|
37
|
-
|
|
37
|
+
injectInitialization = true,
|
|
38
38
|
allowMissingInitialization = false,
|
|
39
39
|
}) {
|
|
40
40
|
const outDir = frameworkOutDir(out, framework, scenarioName)
|
|
@@ -52,9 +52,9 @@ async function runInstrumentedCommand ({
|
|
|
52
52
|
scenarioName,
|
|
53
53
|
...fixtureConfig,
|
|
54
54
|
})
|
|
55
|
-
const validationEnv =
|
|
56
|
-
?
|
|
57
|
-
:
|
|
55
|
+
const validationEnv = injectInitialization
|
|
56
|
+
? buildDatadogEnv({ fixture, outputRoot: rawOutputRoot, scenario: scenarioName, framework })
|
|
57
|
+
: buildOfflineCaptureEnv({ fixture, outputRoot: rawOutputRoot })
|
|
58
58
|
result = await runCommand(command, {
|
|
59
59
|
env: {
|
|
60
60
|
...validationEnv,
|
|
@@ -82,7 +82,7 @@ async function runInstrumentedCommand ({
|
|
|
82
82
|
`${JSON.stringify(sanitizeForReport(result), null, 2)}\n`,
|
|
83
83
|
'scenario result artifact'
|
|
84
84
|
)
|
|
85
|
-
if (!offline.initialized &&
|
|
85
|
+
if (!offline.initialized && injectInitialization && !allowMissingInitialization) {
|
|
86
86
|
const stderr = sanitizeString(result.stderr).trim().slice(-2000)
|
|
87
87
|
throw new Error(
|
|
88
88
|
'Offline Test Optimization exporter did not initialize or write completion evidence. ' +
|
|
@@ -180,11 +180,11 @@ async function prepareGeneratedScenario (framework, scenarioId) {
|
|
|
180
180
|
const scenario = findGeneratedScenario(framework, scenarioId)
|
|
181
181
|
if (!scenario) return { scenario: null, written: [] }
|
|
182
182
|
cleanupGeneratedRuntimeFiles(framework)
|
|
183
|
-
const written = await writeGeneratedFiles(framework)
|
|
183
|
+
const written = await writeGeneratedFiles(framework, scenario)
|
|
184
184
|
return {
|
|
185
185
|
scenario: {
|
|
186
186
|
...scenario,
|
|
187
|
-
runCommand:
|
|
187
|
+
runCommand: getGeneratedCommand(framework, scenario),
|
|
188
188
|
},
|
|
189
189
|
written,
|
|
190
190
|
}
|
|
@@ -314,6 +314,63 @@ async function discoverScenarioTests ({ framework, out, scenarioName, scenario,
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Reports a missing generated test without blaming dd-trace when clean execution was unproven.
|
|
319
|
+
*
|
|
320
|
+
* @param {object} input missing-test evidence
|
|
321
|
+
* @param {object} input.command generated scenario command
|
|
322
|
+
* @param {string} input.diagnosis diagnosis used when clean execution was proven
|
|
323
|
+
* @param {object} input.discovery instrumented baseline result
|
|
324
|
+
* @param {object} input.framework framework manifest entry
|
|
325
|
+
* @param {object} input.options execution options
|
|
326
|
+
* @param {string} input.out validation output root
|
|
327
|
+
* @param {object} input.scenario generated scenario
|
|
328
|
+
* @param {string} input.scenarioName advanced scenario name
|
|
329
|
+
* @returns {object|Promise<object>} incomplete or confirmed failure result
|
|
330
|
+
*/
|
|
331
|
+
function reportMissingGeneratedTest ({
|
|
332
|
+
command,
|
|
333
|
+
diagnosis,
|
|
334
|
+
discovery,
|
|
335
|
+
framework,
|
|
336
|
+
options,
|
|
337
|
+
out,
|
|
338
|
+
scenario,
|
|
339
|
+
scenarioName,
|
|
340
|
+
}) {
|
|
341
|
+
const verification = framework.generatedTestStrategy?.verification?.observedScenarios
|
|
342
|
+
?.find(observed => observed.id === scenario.id)
|
|
343
|
+
const evidence = {
|
|
344
|
+
...discoveryEvidence(discovery),
|
|
345
|
+
generatedVerificationObservedTestCount: verification?.observedTestCount,
|
|
346
|
+
}
|
|
347
|
+
if (verification?.observedTestCount === null) {
|
|
348
|
+
return inconclusive(
|
|
349
|
+
framework,
|
|
350
|
+
scenarioName,
|
|
351
|
+
'The clean temporary validation command exited as expected without a parseable test count, and the ' +
|
|
352
|
+
'instrumented baseline emitted no matching test event. The validator cannot prove that the generated test ' +
|
|
353
|
+
'executed, so no advanced-feature conclusion was reached.',
|
|
354
|
+
{
|
|
355
|
+
...evidence,
|
|
356
|
+
reasonCode: 'generated-test-execution-unproven',
|
|
357
|
+
},
|
|
358
|
+
discovery.outDir
|
|
359
|
+
)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return failWithDebugRerun({
|
|
363
|
+
command,
|
|
364
|
+
diagnosis,
|
|
365
|
+
evidence,
|
|
366
|
+
framework,
|
|
367
|
+
options,
|
|
368
|
+
out,
|
|
369
|
+
outDir: discovery.outDir,
|
|
370
|
+
scenarioName,
|
|
371
|
+
})
|
|
372
|
+
}
|
|
373
|
+
|
|
317
374
|
function testsForDiscoveredScenario (events, scenario, discovery) {
|
|
318
375
|
if (discovery?.testIdentities?.length > 0) {
|
|
319
376
|
return findTestsByIdentity(events, discovery.testIdentities)
|
|
@@ -528,6 +585,7 @@ module.exports = {
|
|
|
528
585
|
inconclusive,
|
|
529
586
|
pass,
|
|
530
587
|
prepareGeneratedScenario,
|
|
588
|
+
reportMissingGeneratedTest,
|
|
531
589
|
requireGeneratedScenario,
|
|
532
590
|
runDebugInstrumentedCommand,
|
|
533
591
|
runInstrumentedCommand,
|
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
failWithDebugRerun,
|
|
10
10
|
pass,
|
|
11
11
|
prepareGeneratedScenario,
|
|
12
|
+
reportMissingGeneratedTest,
|
|
12
13
|
requireGeneratedScenario,
|
|
13
14
|
runInstrumentedCommand,
|
|
14
15
|
testEventSamples,
|
|
@@ -25,14 +26,14 @@ async function runTestManagement ({ framework, out, options }) {
|
|
|
25
26
|
const { scenario } = await prepareGeneratedScenario(framework, 'test-management-target')
|
|
26
27
|
const discovery = await discoverScenarioTests({ framework, out, scenarioName, scenario, options })
|
|
27
28
|
if (discovery.tests.length === 0) {
|
|
28
|
-
return
|
|
29
|
+
return reportMissingGeneratedTest({
|
|
29
30
|
command: scenario.runCommand,
|
|
30
31
|
diagnosis: 'The test-management target was not reported during baseline identity discovery.',
|
|
31
|
-
|
|
32
|
+
discovery,
|
|
32
33
|
framework,
|
|
33
34
|
options,
|
|
34
35
|
out,
|
|
35
|
-
|
|
36
|
+
scenario,
|
|
36
37
|
scenarioName,
|
|
37
38
|
})
|
|
38
39
|
}
|
|
@@ -148,7 +149,7 @@ function buildQuarantinedResponse (framework, scenario, discoveredIdentities = [
|
|
|
148
149
|
for (const identity of identities) {
|
|
149
150
|
for (const suite of getSuiteCandidates(identity, scenario)) {
|
|
150
151
|
for (const name of getNameCandidates(identity)) {
|
|
151
|
-
suites[suite]
|
|
152
|
+
suites[suite] ||= { tests: {} }
|
|
152
153
|
suites[suite].tests[name] = {
|
|
153
154
|
properties: {
|
|
154
155
|
quarantined: true,
|
|
@@ -209,7 +210,7 @@ function summarizeManagedTests (testManagementTests) {
|
|
|
209
210
|
}
|
|
210
211
|
summary.set(displaySuite, testNames)
|
|
211
212
|
}
|
|
212
|
-
return [...summary
|
|
213
|
+
return [...summary].slice(0, 5).map(([suite, tests]) => ({
|
|
213
214
|
suite,
|
|
214
215
|
tests: [...tests].slice(0, 5),
|
|
215
216
|
}))
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Replaces JavaScript comments with spaces while preserving line structure and string literals.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} source JavaScript or TypeScript source
|
|
7
|
+
* @returns {string} source with comments masked
|
|
8
|
+
*/
|
|
9
|
+
function maskJavaScriptComments (source) {
|
|
10
|
+
return maskJavaScriptSource(source, false)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Replaces JavaScript comments and string literals with spaces while preserving line structure.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} source JavaScript or TypeScript source
|
|
17
|
+
* @returns {string} source with non-code text masked
|
|
18
|
+
*/
|
|
19
|
+
function maskJavaScriptNonCode (source) {
|
|
20
|
+
return maskJavaScriptSource(source, true)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Masks comments and optionally string literals in JavaScript-like source.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} source JavaScript or TypeScript source
|
|
27
|
+
* @param {boolean} maskStrings whether string and template literal contents should be masked
|
|
28
|
+
* @returns {string} masked source
|
|
29
|
+
*/
|
|
30
|
+
function maskJavaScriptSource (source, maskStrings) {
|
|
31
|
+
const characters = [...source]
|
|
32
|
+
let blockComment = false
|
|
33
|
+
let lineComment = false
|
|
34
|
+
let quote = ''
|
|
35
|
+
|
|
36
|
+
for (let index = 0; index < characters.length; index++) {
|
|
37
|
+
const character = characters[index]
|
|
38
|
+
const next = characters[index + 1]
|
|
39
|
+
if (lineComment) {
|
|
40
|
+
if (character === '\n') {
|
|
41
|
+
lineComment = false
|
|
42
|
+
} else {
|
|
43
|
+
characters[index] = ' '
|
|
44
|
+
}
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
if (blockComment) {
|
|
48
|
+
if (character === '*' && next === '/') {
|
|
49
|
+
characters[index] = ' '
|
|
50
|
+
characters[++index] = ' '
|
|
51
|
+
blockComment = false
|
|
52
|
+
} else if (character !== '\r' && character !== '\n') {
|
|
53
|
+
characters[index] = ' '
|
|
54
|
+
}
|
|
55
|
+
continue
|
|
56
|
+
}
|
|
57
|
+
if (quote) {
|
|
58
|
+
if (maskStrings && character !== '\r' && character !== '\n') characters[index] = ' '
|
|
59
|
+
if (character.charCodeAt(0) === 92) {
|
|
60
|
+
if (maskStrings && index + 1 < characters.length &&
|
|
61
|
+
characters[index + 1] !== '\r' && characters[index + 1] !== '\n') {
|
|
62
|
+
characters[index + 1] = ' '
|
|
63
|
+
}
|
|
64
|
+
index++
|
|
65
|
+
} else if (character === quote) {
|
|
66
|
+
quote = ''
|
|
67
|
+
}
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
if (character === '"' || character === '\'' || character === '`') {
|
|
71
|
+
quote = character
|
|
72
|
+
if (maskStrings) characters[index] = ' '
|
|
73
|
+
} else if (character === '/' && next === '/') {
|
|
74
|
+
characters[index] = ' '
|
|
75
|
+
characters[++index] = ' '
|
|
76
|
+
lineComment = true
|
|
77
|
+
} else if (character === '/' && next === '*') {
|
|
78
|
+
characters[index] = ' '
|
|
79
|
+
characters[++index] = ' '
|
|
80
|
+
blockComment = true
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return characters.join('')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = { maskJavaScriptComments, maskJavaScriptNonCode }
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const cypressAdapter = require('./framework-adapters/cypress')
|
|
4
|
+
const cucumberAdapter = require('./framework-adapters/cucumber')
|
|
5
|
+
const playwrightAdapter = require('./framework-adapters/playwright')
|
|
6
|
+
|
|
3
7
|
const ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}${String.raw`\[[0-?]*[ -/]*[@-~]`}`, 'g')
|
|
4
8
|
|
|
5
9
|
/**
|
|
@@ -11,16 +15,14 @@ const ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}${String.raw`\[[0-?]*
|
|
|
11
15
|
* @returns {number|null} observed count when a supported summary was found
|
|
12
16
|
*/
|
|
13
17
|
function getObservedTestCount (framework, stdout = '', stderr = '') {
|
|
14
|
-
const output = `${stdout}\n${stderr}
|
|
18
|
+
const output = stripAnsi(`${stdout}\n${stderr}`)
|
|
19
|
+
if (framework === 'cucumber') return cucumberAdapter.getObservedTestCount(output)
|
|
20
|
+
if (framework === 'cypress') return cypressAdapter.getObservedTestCount(output)
|
|
21
|
+
if (framework === 'playwright') return playwrightAdapter.getObservedTestCount(output)
|
|
15
22
|
if (framework === 'jest') return getJestObservedTestCount(output)
|
|
16
23
|
if (framework === 'vitest') return getVitestObservedTestCount(output)
|
|
17
|
-
if (framework === 'playwright') return getPlaywrightObservedTestCount(output)
|
|
18
24
|
|
|
19
|
-
const totalPatterns = framework === 'node:test'
|
|
20
|
-
? [/^# tests\s+(\d+)\s*$/gim]
|
|
21
|
-
: framework === 'cucumber'
|
|
22
|
-
? [/\b(\d+)\s+scenarios?\b/gi]
|
|
23
|
-
: []
|
|
25
|
+
const totalPatterns = framework === 'node:test' ? [/^# tests\s+(\d+)\s*$/gim] : []
|
|
24
26
|
|
|
25
27
|
for (const pattern of totalPatterns) {
|
|
26
28
|
const count = getLastMatchCount(output, pattern)
|
|
@@ -38,20 +40,8 @@ function getObservedTestCount (framework, stdout = '', stderr = '') {
|
|
|
38
40
|
return getLastMatchCount(output, /\b(\d+)\s+tests?\s+(?:passed|failed)\b/gi)
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
*
|
|
44
|
-
* @param {string} output test output without ANSI codes
|
|
45
|
-
* @returns {number|null} executed test count
|
|
46
|
-
*/
|
|
47
|
-
function getPlaywrightObservedTestCount (output) {
|
|
48
|
-
const observed = sumLastMatchCounts(output, [
|
|
49
|
-
/^\s*(\d+)\s+passed\b/gim,
|
|
50
|
-
/^\s*(\d+)\s+failed\b/gim,
|
|
51
|
-
/^\s*(\d+)\s+flaky\b/gim,
|
|
52
|
-
])
|
|
53
|
-
if (observed !== null) return observed
|
|
54
|
-
return /^\s*\d+\s+skipped\b/im.test(output) ? 0 : null
|
|
43
|
+
function stripAnsi (value) {
|
|
44
|
+
return String(value || '').replaceAll(ANSI_PATTERN, '')
|
|
55
45
|
}
|
|
56
46
|
|
|
57
47
|
/**
|
|
@@ -126,4 +116,4 @@ function sumLastMatchCounts (output, patterns) {
|
|
|
126
116
|
return found ? count : null
|
|
127
117
|
}
|
|
128
118
|
|
|
129
|
-
module.exports = { getObservedTestCount }
|
|
119
|
+
module.exports = { getObservedTestCount, stripAnsi }
|