dd-trace 6.16.0 → 6.18.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 +0 -23
- package/ci/test-optimization-validation/approval-artifacts.js +0 -3
- package/ci/test-optimization-validation/approval.js +0 -6
- package/ci/test-optimization-validation/artifact-id.js +0 -1
- package/ci/test-optimization-validation/bounded-json.js +0 -1
- package/ci/test-optimization-validation/cli.js +0 -12
- package/ci/test-optimization-validation/command-output-policy.js +0 -1
- package/ci/test-optimization-validation/command-runner.js +0 -3
- package/ci/test-optimization-validation/environment.js +0 -4
- package/ci/test-optimization-validation/executable-approval.js +0 -1
- package/ci/test-optimization-validation/executable.js +0 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
- package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
- package/ci/test-optimization-validation/generated-test-contract.js +0 -5
- package/ci/test-optimization-validation/generated-verifier.js +0 -1
- package/ci/test-optimization-validation/literal-environment.js +0 -1
- package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
- package/ci/test-optimization-validation/manifest-schema.js +0 -21
- package/ci/test-optimization-validation/offline-fixtures.js +0 -4
- package/ci/test-optimization-validation/plan-writer.js +0 -11
- package/ci/test-optimization-validation/preflight-runner.js +0 -1
- package/ci/test-optimization-validation/redaction.js +0 -4
- package/ci/test-optimization-validation/report-writer.js +0 -16
- package/ci/test-optimization-validation/runner-command.js +0 -3
- package/ci/test-optimization-validation/runner-contract.js +0 -4
- package/ci/test-optimization-validation/safe-files.js +0 -1
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +0 -1
- package/ci/test-optimization-validation/source-text.js +0 -3
- package/ci/vitest-no-worker-init-setup.mjs +41 -16
- package/index.d.ts +208 -0
- package/package.json +17 -16
- package/packages/datadog-esbuild/src/utils.js +0 -2
- package/packages/datadog-instrumentations/src/aerospike.js +28 -6
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/console.js +97 -0
- package/packages/datadog-instrumentations/src/cucumber.js +77 -12
- package/packages/datadog-instrumentations/src/cypress-config.js +27 -38
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -6
- package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +0 -3
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
- package/packages/datadog-instrumentations/src/helpers/register.js +24 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +111 -26
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +55 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +28 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +20 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
- package/packages/datadog-instrumentations/src/jest.js +165 -51
- package/packages/datadog-instrumentations/src/knex.js +0 -1
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
- package/packages/datadog-instrumentations/src/mariadb.js +0 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +25 -26
- package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
- package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
- package/packages/datadog-instrumentations/src/mysql2.js +0 -2
- package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
- package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
- package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
- package/packages/datadog-instrumentations/src/openai.js +51 -12
- package/packages/datadog-instrumentations/src/oracledb.js +9 -3
- package/packages/datadog-instrumentations/src/playwright-reporter.js +6 -20
- package/packages/datadog-instrumentations/src/playwright.js +280 -56
- package/packages/datadog-instrumentations/src/{azure-cosmos.js → postgres.js} +1 -1
- package/packages/datadog-instrumentations/src/router.js +0 -2
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
- package/packages/datadog-instrumentations/src/sequelize.js +0 -1
- package/packages/datadog-instrumentations/src/supabase.js +15 -0
- package/packages/datadog-instrumentations/src/undici.js +7 -3
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
- package/packages/datadog-instrumentations/src/vitest-main.js +121 -30
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
- package/packages/datadog-instrumentations/src/vitest-worker.js +49 -13
- package/packages/datadog-instrumentations/src/webdriverio.js +44 -47
- package/packages/datadog-instrumentations/src/ws.js +41 -2
- package/packages/datadog-plugin-ai/src/utils.js +0 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +0 -1
- package/packages/datadog-plugin-cucumber/src/index.js +9 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +211 -85
- package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
- package/packages/datadog-plugin-cypress/src/index.js +3 -1
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
- package/packages/datadog-plugin-cypress/src/support.js +52 -7
- package/packages/datadog-plugin-graphql/src/resolve-error.js +1 -2
- package/packages/datadog-plugin-graphql/src/utils.js +0 -5
- package/packages/datadog-plugin-jest/src/index.js +12 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +38 -11
- package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
- package/packages/datadog-plugin-openai/src/index.js +16 -1
- package/packages/datadog-plugin-openai/src/realtime.js +144 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
- package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
- package/packages/datadog-plugin-playwright/src/index.js +81 -9
- package/packages/datadog-plugin-postgres/src/index.js +167 -0
- package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
- package/packages/datadog-plugin-redis/src/index.js +15 -1
- package/packages/datadog-plugin-supabase/src/error.js +18 -0
- package/packages/datadog-plugin-supabase/src/index.js +21 -0
- package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
- package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
- package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
- package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
- package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
- package/packages/datadog-plugin-supabase/src/url.js +17 -0
- package/packages/datadog-plugin-vitest/src/index.js +9 -0
- package/packages/datadog-plugin-ws/src/producer.js +1 -1
- package/packages/datadog-plugin-ws/src/util.js +0 -4
- package/packages/datadog-shimmer/src/shimmer.js +14 -10
- package/packages/datadog-turbopack/index.js +4 -7
- package/packages/datadog-turbopack/src/loader.js +6 -18
- package/packages/datadog-webpack/src/loader.js +0 -1
- package/packages/dd-trace/src/agent/info.js +5 -4
- package/packages/dd-trace/src/aiguard/client.js +2 -3
- package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
- package/packages/dd-trace/src/aiguard/index.js +2 -2
- package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
- package/packages/dd-trace/src/aiguard/integrations/openai.js +81 -7
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
- package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
- package/packages/dd-trace/src/aiguard/messages/utils.js +0 -1
- package/packages/dd-trace/src/aiguard/redaction.js +0 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/activation.js +1 -1
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
- package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
- package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
- package/packages/dd-trace/src/appsec/index.js +2 -2
- package/packages/dd-trace/src/appsec/lambda.js +71 -2
- package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config.js +8 -6
- package/packages/dd-trace/src/appsec/reporter.js +10 -6
- package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
- package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
- package/packages/dd-trace/src/carrier.js +0 -5
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
- package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
- package/packages/dd-trace/src/config/defaults.js +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +88 -82
- package/packages/dd-trace/src/config/helper.js +0 -1
- package/packages/dd-trace/src/config/index.js +31 -30
- package/packages/dd-trace/src/config/parsers.js +34 -6
- package/packages/dd-trace/src/config/remote_config.js +25 -109
- package/packages/dd-trace/src/config/supported-configurations.json +150 -10
- package/packages/dd-trace/src/datastreams/encoding.js +0 -1
- package/packages/dd-trace/src/datastreams/pathway.js +0 -1
- package/packages/dd-trace/src/debugger/constants.js +10 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +62 -10
- package/packages/dd-trace/src/debugger/devtools_client/config.js +4 -1
- package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
- package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +21 -8
- package/packages/dd-trace/src/debugger/devtools_client/send.js +41 -15
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +5 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +21 -7
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
- package/packages/dd-trace/src/debugger/index.js +51 -3
- package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
- package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
- package/packages/dd-trace/src/dogstatsd.js +0 -23
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
- package/packages/dd-trace/src/encode/0.4.js +0 -7
- package/packages/dd-trace/src/encode/0.5.js +0 -2
- package/packages/dd-trace/src/encode/tags-processors.js +0 -1
- package/packages/dd-trace/src/evp_proxy/constants.js +2 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +17 -13
- package/packages/dd-trace/src/evp_proxy/discovery.js +14 -11
- package/packages/dd-trace/src/evp_proxy/path.js +21 -9
- package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
- package/packages/dd-trace/src/exporters/common/request.js +1 -0
- package/packages/dd-trace/src/exporters/common/url.js +33 -4
- package/packages/dd-trace/src/exporters/common/writer.js +0 -2
- package/packages/dd-trace/src/id.js +0 -11
- package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
- package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
- package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
- package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
- package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
- package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
- package/packages/dd-trace/src/llmobs/index.js +1 -3
- package/packages/dd-trace/src/llmobs/noop.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
- package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
- package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +647 -0
- package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +158 -0
- package/packages/dd-trace/src/llmobs/sdk.js +21 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
- package/packages/dd-trace/src/llmobs/tagger.js +39 -11
- package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
- package/packages/dd-trace/src/llmobs/util.js +0 -34
- package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
- package/packages/dd-trace/src/log/channels.js +3 -0
- package/packages/dd-trace/src/log/index.js +23 -5
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
- package/packages/dd-trace/src/msgpack/chunk.js +0 -1
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
- package/packages/dd-trace/src/openfeature/configuration_source.js +4 -1
- package/packages/dd-trace/src/openfeature/encoding.js +0 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -3
- package/packages/dd-trace/src/openfeature/index.js +6 -6
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
- package/packages/dd-trace/src/openfeature/writers/base.js +90 -23
- package/packages/dd-trace/src/openfeature/writers/exposures.js +4 -5
- package/packages/dd-trace/src/openfeature/writers/util.js +104 -37
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -14
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +30 -13
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
- package/packages/dd-trace/src/opentracing/span_context.js +0 -1
- package/packages/dd-trace/src/opentracing/tracer.js +3 -3
- package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
- package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
- package/packages/dd-trace/src/plugin_manager.js +27 -8
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -2
- package/packages/dd-trace/src/plugins/database.js +2 -6
- package/packages/dd-trace/src/plugins/index.js +7 -0
- package/packages/dd-trace/src/plugins/plugin.js +0 -4
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +1 -3
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
- package/packages/dd-trace/src/plugins/util/llm.js +0 -2
- package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
- package/packages/dd-trace/src/plugins/util/test.js +26 -20
- package/packages/dd-trace/src/plugins/util/url.js +0 -5
- package/packages/dd-trace/src/priority_sampler.js +0 -6
- package/packages/dd-trace/src/process-tags/index.js +0 -1
- package/packages/dd-trace/src/profiler.js +132 -35
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
- package/packages/dd-trace/src/profiling/profiler.js +101 -41
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
- package/packages/dd-trace/src/propagation-hash/index.js +0 -1
- package/packages/dd-trace/src/proxy.js +23 -47
- package/packages/dd-trace/src/random_sampler.js +0 -4
- package/packages/dd-trace/src/rate_limiter.js +0 -4
- package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
- package/packages/dd-trace/src/remote_config/index.js +0 -1
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
- package/packages/dd-trace/src/sampler.js +0 -4
- package/packages/dd-trace/src/sampling_rule.js +0 -7
- package/packages/dd-trace/src/serverless/vercel.js +0 -1
- package/packages/dd-trace/src/serverless.js +0 -1
- package/packages/dd-trace/src/service-naming/index.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_sampler.js +0 -1
- package/packages/dd-trace/src/standalone/product.js +2 -2
- package/packages/dd-trace/src/standalone/tracesource.js +0 -1
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
- package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
- package/packages/dd-trace/src/telemetry/metrics.js +0 -2
- package/packages/dd-trace/src/telemetry/send-data.js +2 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
- package/packages/dd-trace/src/tracer.js +5 -4
- package/packages/dd-trace/src/util.js +13 -1
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/packages/datadog-instrumentations/src/bullmq.js +0 -11
- package/packages/datadog-instrumentations/src/langchain.js +0 -7
- package/packages/datadog-instrumentations/src/langgraph.js +0 -7
- package/packages/datadog-instrumentations/src/mercurius.js +0 -11
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
hasEfdRetries,
|
|
15
15
|
shouldSkipEfdRetry,
|
|
16
16
|
} = require('../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
17
|
+
const { getDynamicAtrRetryCount } = require('../../dd-trace/src/ci-visibility/dynamic-atr-retries')
|
|
17
18
|
const {
|
|
18
19
|
parseAnnotations,
|
|
19
20
|
getTestSuitePath,
|
|
@@ -65,8 +66,10 @@ const testPageGotoCh = channel('ci:playwright:test:page-goto')
|
|
|
65
66
|
|
|
66
67
|
const dispatcherRunCh = tracingChannel('orchestrion:playwright:Dispatcher_run')
|
|
67
68
|
const dispatcherCreateWorkerCh = tracingChannel('orchestrion:playwright:Dispatcher_createWorker')
|
|
69
|
+
const filterForShardCh = tracingChannel('orchestrion:playwright:filterForShard')
|
|
68
70
|
const processHostStartRunnerCh = tracingChannel('orchestrion:playwright:ProcessHost_startRunner')
|
|
69
71
|
const createRootSuiteCh = tracingChannel('orchestrion:playwright:createRootSuite')
|
|
72
|
+
const lastRunTestIdCh = tracingChannel('orchestrion:playwright:lastRunTestId')
|
|
70
73
|
const artifactsRecorderScreenshotPathCh =
|
|
71
74
|
tracingChannel('orchestrion:playwright:ArtifactsRecorder_createScreenshotAttachmentPath')
|
|
72
75
|
const snapshotRecorderScreenshotPathCh = tracingChannel('orchestrion:playwright:SnapshotRecorder_createAttachmentPath')
|
|
@@ -74,6 +77,7 @@ const saveAutomaticVideoCh = tracingChannel('orchestrion:playwright:saveAutomati
|
|
|
74
77
|
const pageGotoCh = tracingChannel('orchestrion:playwright-core:Page_goto')
|
|
75
78
|
|
|
76
79
|
const testToCtx = new WeakMap()
|
|
80
|
+
const originalTestIdsByRetry = new WeakMap()
|
|
77
81
|
const testSuiteToCtx = new Map()
|
|
78
82
|
const testSuiteToTestStatuses = new Map()
|
|
79
83
|
const testSuiteToErrors = new Map()
|
|
@@ -112,6 +116,8 @@ let isEarlyFlakeDetectionFaulty = false
|
|
|
112
116
|
let earlyFlakeDetectionFaultyThreshold = 0
|
|
113
117
|
let isFlakyTestRetriesEnabled = false
|
|
114
118
|
let flakyTestRetriesCount = 0
|
|
119
|
+
let isDynamicAtrEnabled = false
|
|
120
|
+
let dynamicAtrBuckets
|
|
115
121
|
let knownTests = {}
|
|
116
122
|
let isTestManagementTestsEnabled = false
|
|
117
123
|
let testManagementAttemptToFixRetries = 0
|
|
@@ -121,6 +127,9 @@ let modifiedFiles = {}
|
|
|
121
127
|
let playwrightRunSummary
|
|
122
128
|
let recordedTestOptimizationExecutions = new Set()
|
|
123
129
|
let testsReportedInGenerateSummary = new Set()
|
|
130
|
+
let reportedTestExecutions = new WeakMap()
|
|
131
|
+
let hasTestsAssignedToShard = false
|
|
132
|
+
let hasTestsBeforeSharding = false
|
|
124
133
|
const newTestsWithDynamicNames = new Set()
|
|
125
134
|
const attemptToFixExecutions = new Map()
|
|
126
135
|
const loggedAttemptToFixTests = new Set()
|
|
@@ -131,6 +140,8 @@ const efdRetryTestsById = new Map()
|
|
|
131
140
|
const efdScheduledOriginalTestKeys = new Set()
|
|
132
141
|
const efdStartedOriginalTestKeys = new Set()
|
|
133
142
|
const efdSlowAbortedTests = new Set()
|
|
143
|
+
const dynamicAtrRetryCountByTestKey = new Map()
|
|
144
|
+
const automaticRetryProjects = new Set()
|
|
134
145
|
const ddPropertiesByTestId = new Map()
|
|
135
146
|
const ddPropertiesRequestsByTestId = new Map()
|
|
136
147
|
const disabledTestIds = new Set()
|
|
@@ -159,7 +170,6 @@ const automaticFailureVideoPaths = new Set()
|
|
|
159
170
|
* Returns whether Playwright's internal screenshot recorder created an attachment.
|
|
160
171
|
*
|
|
161
172
|
* @param {object} attachment - Playwright attachment payload
|
|
162
|
-
* @returns {boolean}
|
|
163
173
|
*/
|
|
164
174
|
function isAutomaticFailureScreenshotAttachment (attachment) {
|
|
165
175
|
return typeof attachment?.path === 'string' && automaticFailureScreenshotPaths.delete(attachment.path)
|
|
@@ -169,7 +179,6 @@ function isAutomaticFailureScreenshotAttachment (attachment) {
|
|
|
169
179
|
* Returns whether Playwright's internal video recorder created an attachment.
|
|
170
180
|
*
|
|
171
181
|
* @param {object} attachment - Playwright attachment payload
|
|
172
|
-
* @returns {boolean}
|
|
173
182
|
*/
|
|
174
183
|
function isAutomaticFailureVideoAttachment (attachment) {
|
|
175
184
|
return typeof attachment?.path === 'string' && automaticFailureVideoPaths.delete(attachment.path)
|
|
@@ -230,7 +239,6 @@ function getTestRepeatEachKey (test) {
|
|
|
230
239
|
|
|
231
240
|
/**
|
|
232
241
|
* @param {object} test
|
|
233
|
-
* @returns {string}
|
|
234
242
|
*/
|
|
235
243
|
function getTestEfdKey (test) {
|
|
236
244
|
const projectKey = getTestProjectKey(test)
|
|
@@ -263,9 +271,6 @@ function registerEfdRetryTest (test) {
|
|
|
263
271
|
})
|
|
264
272
|
}
|
|
265
273
|
|
|
266
|
-
/**
|
|
267
|
-
* @returns {boolean}
|
|
268
|
-
*/
|
|
269
274
|
function shouldRunEarlyFlakeDetection () {
|
|
270
275
|
return isEarlyFlakeDetectionEnabled && hasEfdRetries(earlyFlakeDetectionRetryPolicy)
|
|
271
276
|
}
|
|
@@ -389,7 +394,6 @@ function sendDdPropertiesToWorkerWhenAvailable (workerProcess, testId) {
|
|
|
389
394
|
|
|
390
395
|
/**
|
|
391
396
|
* @param {object} test
|
|
392
|
-
* @returns {boolean}
|
|
393
397
|
*/
|
|
394
398
|
function shouldRequestEfdRetryCount (test) {
|
|
395
399
|
// The main process remains the source of truth. repeatEachIndex is only used as
|
|
@@ -473,6 +477,7 @@ function deepCloneSuite (suite, filterTest, tags = [], configureCopiedTest) {
|
|
|
473
477
|
} else {
|
|
474
478
|
if (filterTest(entry)) {
|
|
475
479
|
const copiedTest = entry._clone()
|
|
480
|
+
originalTestIdsByRetry.set(copiedTest, originalTestIdsByRetry.get(entry) ?? entry.id)
|
|
476
481
|
if (configureCopiedTest) {
|
|
477
482
|
configureCopiedTest(copiedTest, entry)
|
|
478
483
|
}
|
|
@@ -519,6 +524,8 @@ function getTestsBySuiteFromTestsById (testsById) {
|
|
|
519
524
|
}
|
|
520
525
|
|
|
521
526
|
function getPlaywrightConfig (playwrightRunner) {
|
|
527
|
+
if (!playwrightRunner) return {}
|
|
528
|
+
|
|
522
529
|
try {
|
|
523
530
|
return playwrightRunner._configLoader.fullConfig()
|
|
524
531
|
} catch {
|
|
@@ -558,7 +565,6 @@ function getProjectsFromRunner (runner, configArg) {
|
|
|
558
565
|
* Returns whether at least one Playwright project captures automatic screenshots for failed tests.
|
|
559
566
|
*
|
|
560
567
|
* @param {Array<object>} projects - Playwright projects with resolved use options
|
|
561
|
-
* @returns {boolean} Whether failure screenshot capture is enabled
|
|
562
568
|
*/
|
|
563
569
|
function isFailureScreenshotCaptureEnabled (projects) {
|
|
564
570
|
for (const project of projects) {
|
|
@@ -575,7 +581,6 @@ function isFailureScreenshotCaptureEnabled (projects) {
|
|
|
575
581
|
* Returns whether at least one Playwright project records videos that can be retained for failures.
|
|
576
582
|
*
|
|
577
583
|
* @param {Array<object>} projects - Playwright projects with resolved use options
|
|
578
|
-
* @returns {boolean} Whether video capture is enabled
|
|
579
584
|
*/
|
|
580
585
|
function isFailureVideoCaptureEnabled (projects) {
|
|
581
586
|
for (const project of projects) {
|
|
@@ -599,14 +604,19 @@ function getProjectsFromDispatcher (dispatcher) {
|
|
|
599
604
|
return dispatcher._loader?.fullConfig()?.projects
|
|
600
605
|
}
|
|
601
606
|
|
|
602
|
-
|
|
607
|
+
/**
|
|
608
|
+
* Resolves the configured project by Playwright's unique ID or legacy index.
|
|
609
|
+
* @param {object[]} projects
|
|
610
|
+
* @param {object} test
|
|
611
|
+
*/
|
|
612
|
+
function getTestProject (projects, test) {
|
|
603
613
|
if (!projects || !test) {
|
|
604
614
|
return null
|
|
605
615
|
}
|
|
606
616
|
const { _projectIndex, _projectId: testProjectId } = test
|
|
607
617
|
|
|
608
618
|
if (_projectIndex !== undefined) {
|
|
609
|
-
return projects[_projectIndex]
|
|
619
|
+
return projects[_projectIndex]
|
|
610
620
|
}
|
|
611
621
|
|
|
612
622
|
return projects.find(({ __projectId, _id, name }) => {
|
|
@@ -617,7 +627,12 @@ function getBrowserNameFromProjects (projects, test) {
|
|
|
617
627
|
return _id === testProjectId
|
|
618
628
|
}
|
|
619
629
|
return name === testProjectId
|
|
620
|
-
})
|
|
630
|
+
})
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function getBrowserNameFromProjects (projects, test) {
|
|
634
|
+
const project = getTestProject(projects, test)
|
|
635
|
+
return project && project.name
|
|
621
636
|
}
|
|
622
637
|
|
|
623
638
|
function formatTestHookError (error, hookType, isTimeout) {
|
|
@@ -671,8 +686,8 @@ function getTestByTestId (dispatcher, testId) {
|
|
|
671
686
|
// Inspired by https://github.com/microsoft/playwright/blob/2b77ed4d7aafa85a600caa0b0d101b72c8437eeb/packages/playwright/src/reporters/base.ts#L293
|
|
672
687
|
// We can't use test.outcome() directly because it's set on follow up handlers:
|
|
673
688
|
// our `testEndHandler` is called before the outcome is set.
|
|
674
|
-
function testWillRetry (test,
|
|
675
|
-
return
|
|
689
|
+
function testWillRetry (test, status, expectedStatus = test.expectedStatus) {
|
|
690
|
+
return status !== 'skipped' && status !== expectedStatus && test.results.length <= test.retries
|
|
676
691
|
}
|
|
677
692
|
|
|
678
693
|
function getFinalStatus ({
|
|
@@ -682,7 +697,6 @@ function getFinalStatus ({
|
|
|
682
697
|
isAtrRetry,
|
|
683
698
|
isEfdManagedTest,
|
|
684
699
|
isAttemptToFix,
|
|
685
|
-
hasFailedAllRetries,
|
|
686
700
|
hasFailedAttemptToFixRetries,
|
|
687
701
|
hasPassedAnyEfdAttempt,
|
|
688
702
|
testStatus,
|
|
@@ -694,7 +708,7 @@ function getFinalStatus ({
|
|
|
694
708
|
return 'skip'
|
|
695
709
|
}
|
|
696
710
|
if (isAtrRetry) {
|
|
697
|
-
return
|
|
711
|
+
return testStatus
|
|
698
712
|
}
|
|
699
713
|
if (isEfdManagedTest) {
|
|
700
714
|
return hasPassedAnyEfdAttempt ? 'pass' : 'fail'
|
|
@@ -705,6 +719,17 @@ function getFinalStatus ({
|
|
|
705
719
|
return testStatus
|
|
706
720
|
}
|
|
707
721
|
|
|
722
|
+
/**
|
|
723
|
+
* Reports whether another test in the serial group can trigger this test to run again.
|
|
724
|
+
* @param {object} test
|
|
725
|
+
*/
|
|
726
|
+
function isSerialTest (test) {
|
|
727
|
+
for (let suite = test.parent; suite; suite = suite.parent) {
|
|
728
|
+
if (suite._parallelMode === 'serial') return true
|
|
729
|
+
}
|
|
730
|
+
return false
|
|
731
|
+
}
|
|
732
|
+
|
|
708
733
|
function getTestFullname (test) {
|
|
709
734
|
let parent = test.parent
|
|
710
735
|
const names = [test.title]
|
|
@@ -789,7 +814,6 @@ function testBeginHandler (test, browserName, shouldCreateTestSpan) {
|
|
|
789
814
|
*
|
|
790
815
|
* @param {object} test
|
|
791
816
|
* @param {string} testSuiteAbsolutePath
|
|
792
|
-
* @returns {void}
|
|
793
817
|
*/
|
|
794
818
|
function recordSkippedTestOptimizationExecution (test, testSuiteAbsolutePath) {
|
|
795
819
|
if (recordedTestOptimizationExecutions.has(test) ||
|
|
@@ -852,6 +876,37 @@ function finishTestSuiteIfDone (testSuiteAbsolutePath, projects) {
|
|
|
852
876
|
}
|
|
853
877
|
}
|
|
854
878
|
|
|
879
|
+
/**
|
|
880
|
+
* Checks whether a test inherits the retry limit assigned by Test Optimization.
|
|
881
|
+
* @param {object} test
|
|
882
|
+
* @param {object[]} projects
|
|
883
|
+
*/
|
|
884
|
+
function hasAutomaticRetries (test, projects) {
|
|
885
|
+
if (!automaticRetryProjects.has(getTestProject(projects, test))) return false
|
|
886
|
+
for (let suite = test.parent; suite; suite = suite.parent) {
|
|
887
|
+
if (suite._retries !== undefined) return false
|
|
888
|
+
}
|
|
889
|
+
return true
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Records a completed test in its suite and removes it from pending executions.
|
|
894
|
+
* @param {object} test
|
|
895
|
+
* @param {string} testStatus
|
|
896
|
+
* @param {object} [error]
|
|
897
|
+
*/
|
|
898
|
+
function recordFinalTestStatus (test, testStatus, error) {
|
|
899
|
+
const testSuiteAbsolutePath = test._requireFile
|
|
900
|
+
if (testSuiteToTestStatuses.has(testSuiteAbsolutePath)) {
|
|
901
|
+
testSuiteToTestStatuses.get(testSuiteAbsolutePath).push(testStatus)
|
|
902
|
+
} else {
|
|
903
|
+
testSuiteToTestStatuses.set(testSuiteAbsolutePath, [testStatus])
|
|
904
|
+
}
|
|
905
|
+
if (error) addErrorToTestSuite(testSuiteAbsolutePath, error)
|
|
906
|
+
remainingTestsByFile[testSuiteAbsolutePath] = remainingTestsByFile[testSuiteAbsolutePath]
|
|
907
|
+
.filter(currentTest => currentTest !== test)
|
|
908
|
+
}
|
|
909
|
+
|
|
855
910
|
function testEndHandler ({
|
|
856
911
|
test,
|
|
857
912
|
annotations,
|
|
@@ -860,6 +915,10 @@ function testEndHandler ({
|
|
|
860
915
|
isTimeout,
|
|
861
916
|
shouldCreateTestSpan,
|
|
862
917
|
projects,
|
|
918
|
+
testDuration,
|
|
919
|
+
testResultStatus,
|
|
920
|
+
expectedStatus = test.expectedStatus,
|
|
921
|
+
hasNonRetriableError,
|
|
863
922
|
}) {
|
|
864
923
|
const {
|
|
865
924
|
_requireFile: testSuiteAbsolutePath,
|
|
@@ -892,19 +951,23 @@ function testEndHandler ({
|
|
|
892
951
|
|
|
893
952
|
const isEfdManagedTest = isTestEfdManaged(test)
|
|
894
953
|
const testFqn = getTestFullyQualifiedName(test)
|
|
895
|
-
|
|
954
|
+
// Dynamic ATR budgets and retry status must be isolated per Playwright project.
|
|
955
|
+
const testStatusKey = (isEfdManagedTest || isDynamicAtrEnabled) ? getTestEfdKey(test) : testFqn
|
|
896
956
|
const testStatuses = testsToTestStatuses.get(testStatusKey) || []
|
|
897
957
|
|
|
898
958
|
if (testStatuses.length === 0) {
|
|
899
|
-
testsToTestStatuses.set(testStatusKey,
|
|
959
|
+
testsToTestStatuses.set(testStatusKey, testStatuses)
|
|
900
960
|
if (test._ddIsNew && DYNAMIC_NAME_RE.test(getTestFullname(test))) {
|
|
901
961
|
newTestsWithDynamicNames.add(`${getTestSuitePath(test._requireFile, rootDir)} › ${getTestFullname(test)}`)
|
|
902
962
|
}
|
|
903
|
-
}
|
|
904
|
-
|
|
963
|
+
}
|
|
964
|
+
testStatuses.push(testStatus)
|
|
965
|
+
if (testStatus === 'pass' || testStatus === 'fail') {
|
|
966
|
+
reportedTestExecutions.set(test, { status: testStatus, error })
|
|
905
967
|
}
|
|
906
968
|
|
|
907
969
|
const testEfdKey = getTestEfdKey(test)
|
|
970
|
+
const dynamicAtrTestKey = testEfdKey
|
|
908
971
|
if (isEfdManagedTest && !test._ddIsEfdRetry && !efdRetryCountByTestKey.has(testEfdKey)) {
|
|
909
972
|
const testResult = results.at(-1)
|
|
910
973
|
const duration = testResult?.duration > 0 ? testResult.duration : performance.now() - test._ddStartTime
|
|
@@ -916,6 +979,23 @@ function testEndHandler ({
|
|
|
916
979
|
}
|
|
917
980
|
|
|
918
981
|
const testProperties = getTestProperties(test)
|
|
982
|
+
if (
|
|
983
|
+
isDynamicAtrEnabled &&
|
|
984
|
+
isFlakyTestRetriesEnabled &&
|
|
985
|
+
!testProperties.attemptToFix &&
|
|
986
|
+
!test._ddIsEfdRetry &&
|
|
987
|
+
!isEfdManagedTest &&
|
|
988
|
+
hasAutomaticRetries(test, projects) &&
|
|
989
|
+
!dynamicAtrRetryCountByTestKey.has(dynamicAtrTestKey)
|
|
990
|
+
) {
|
|
991
|
+
const testResult = results.at(-1)
|
|
992
|
+
const duration = testDuration ??
|
|
993
|
+
(testResult?.duration > 0 ? testResult.duration : performance.now() - test._ddStartTime)
|
|
994
|
+
const retryCount = getDynamicAtrRetryCount(duration, earlyFlakeDetectionRetryPolicy, dynamicAtrBuckets)
|
|
995
|
+
dynamicAtrRetryCountByTestKey.set(dynamicAtrTestKey, retryCount)
|
|
996
|
+
// Serial groups may skip this test before its first actual execution.
|
|
997
|
+
test.retries = (testResult?.retry ?? 0) + retryCount
|
|
998
|
+
}
|
|
919
999
|
const hasRecordedTestOptimizationExecution = recordedTestOptimizationExecutions.has(test)
|
|
920
1000
|
|
|
921
1001
|
if (!hasRecordedTestOptimizationExecution) {
|
|
@@ -968,34 +1048,40 @@ function testEndHandler ({
|
|
|
968
1048
|
test._ddHasFailedAllRetries = true
|
|
969
1049
|
}
|
|
970
1050
|
|
|
971
|
-
|
|
1051
|
+
const willRetry = testWillRetry(test, testResultStatus, expectedStatus)
|
|
1052
|
+
|
|
1053
|
+
// ATR: use the effective native limit for tests with explicit Playwright retries.
|
|
1054
|
+
const atrRetryCount = isDynamicAtrEnabled
|
|
1055
|
+
? dynamicAtrRetryCountByTestKey.get(dynamicAtrTestKey) ?? test.retries
|
|
1056
|
+
: flakyTestRetriesCount
|
|
972
1057
|
if (isFlakyTestRetriesEnabled && !testProperties.attemptToFix && !test._ddIsEfdRetry &&
|
|
973
1058
|
!(test._ddIsNew || test._ddIsModified) &&
|
|
974
|
-
|
|
975
|
-
|
|
1059
|
+
atrRetryCount != null && atrRetryCount > 0 &&
|
|
1060
|
+
!willRetry && testResultStatus !== expectedStatus &&
|
|
976
1061
|
testStatuses.every(status => status === 'fail')) {
|
|
977
1062
|
test._ddHasFailedAllRetries = true
|
|
978
1063
|
}
|
|
979
1064
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
// this handles tests that do not go through the worker process (because they're skipped)
|
|
1065
|
+
// Legacy Playwright also creates executed test spans in the main process.
|
|
983
1066
|
if (shouldCreateTestSpan) {
|
|
984
1067
|
const testResult = results.at(-1)
|
|
985
1068
|
const testCtx = testToCtx.get(test)
|
|
1069
|
+
const retryTestId = testStatus !== 'skip' && !isEfdManagedTest &&
|
|
1070
|
+
!test._ddIsAttemptToFix && test.retries > 0
|
|
1071
|
+
? test.id ?? test._id
|
|
1072
|
+
: undefined
|
|
986
1073
|
const isAtrRetry = testResult?.retry > 0 &&
|
|
987
1074
|
isFlakyTestRetriesEnabled &&
|
|
988
1075
|
!test._ddIsAttemptToFix &&
|
|
989
1076
|
!test._ddIsEfdRetry
|
|
990
1077
|
|
|
991
1078
|
const finalStatus = getFinalStatus({
|
|
992
|
-
isFinalExecution: !willRetry,
|
|
1079
|
+
isFinalExecution: retryTestId !== undefined || !willRetry,
|
|
993
1080
|
isDisabled: test._ddIsDisabled,
|
|
994
1081
|
isQuarantined: test._ddIsQuarantined,
|
|
995
1082
|
isAtrRetry,
|
|
996
1083
|
isEfdManagedTest,
|
|
997
1084
|
isAttemptToFix: test._ddIsAttemptToFix,
|
|
998
|
-
hasFailedAllRetries: test._ddHasFailedAllRetries,
|
|
999
1085
|
hasFailedAttemptToFixRetries: test._ddHasFailedAttemptToFixRetries,
|
|
1000
1086
|
hasPassedAnyEfdAttempt: testStatuses.includes('pass'),
|
|
1001
1087
|
testStatus,
|
|
@@ -1005,6 +1091,8 @@ function testEndHandler ({
|
|
|
1005
1091
|
if (testCtx) {
|
|
1006
1092
|
testFinishCh.publish({
|
|
1007
1093
|
testStatus,
|
|
1094
|
+
isExpectedFailure: testResultStatus === 'failed' && expectedStatus === 'failed',
|
|
1095
|
+
hasNonRetriableError,
|
|
1008
1096
|
steps: testResult?.steps || [],
|
|
1009
1097
|
isRetry: testResult?.retry > 0,
|
|
1010
1098
|
error,
|
|
@@ -1021,28 +1109,15 @@ function testEndHandler ({
|
|
|
1021
1109
|
isAtrRetry,
|
|
1022
1110
|
isModified: test._ddIsModified,
|
|
1023
1111
|
finalStatus,
|
|
1112
|
+
retryTestId,
|
|
1113
|
+
deferFinalStatus: willRetry,
|
|
1024
1114
|
earlyFlakeAbortReason: efdSlowAbortedTests.has(testEfdKey) ? 'slow' : undefined,
|
|
1025
1115
|
...testCtx.currentStore,
|
|
1026
1116
|
})
|
|
1027
1117
|
}
|
|
1028
1118
|
}
|
|
1029
1119
|
|
|
1030
|
-
if (!willRetry)
|
|
1031
|
-
if (testSuiteToTestStatuses.has(testSuiteAbsolutePath)) {
|
|
1032
|
-
testSuiteToTestStatuses.get(testSuiteAbsolutePath).push(testStatus)
|
|
1033
|
-
} else {
|
|
1034
|
-
testSuiteToTestStatuses.set(testSuiteAbsolutePath, [testStatus])
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
if (error) {
|
|
1038
|
-
addErrorToTestSuite(testSuiteAbsolutePath, error)
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
if (!willRetry) {
|
|
1043
|
-
remainingTestsByFile[testSuiteAbsolutePath] = remainingTestsByFile[testSuiteAbsolutePath]
|
|
1044
|
-
.filter(currentTest => currentTest !== test)
|
|
1045
|
-
}
|
|
1120
|
+
if (!willRetry) recordFinalTestStatus(test, testStatus, error)
|
|
1046
1121
|
|
|
1047
1122
|
finishTestSuiteIfDone(testSuiteAbsolutePath, projects)
|
|
1048
1123
|
}
|
|
@@ -1050,10 +1125,35 @@ function testEndHandler ({
|
|
|
1050
1125
|
function dispatcherRunWrapper (run) {
|
|
1051
1126
|
return function (...args) {
|
|
1052
1127
|
remainingTestsByFile = getTestsBySuiteFromTestsById(this._testById)
|
|
1128
|
+
for (const tests of Object.values(remainingTestsByFile)) {
|
|
1129
|
+
if (tests.length > 0) {
|
|
1130
|
+
hasTestsAssignedToShard = true
|
|
1131
|
+
break
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1053
1134
|
return run.apply(this, args)
|
|
1054
1135
|
}
|
|
1055
1136
|
}
|
|
1056
1137
|
|
|
1138
|
+
function recordTestsBeforeSharding (testGroups) {
|
|
1139
|
+
hasTestsBeforeSharding = testGroups.some(group => group.tests.length > 0)
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
function testGroupsHook (testGroupsPackage) {
|
|
1143
|
+
const filterForShard = testGroupsPackage.filterForShard
|
|
1144
|
+
const wrappedFilterForShard = function (...args) {
|
|
1145
|
+
recordTestsBeforeSharding(args.at(-1))
|
|
1146
|
+
return filterForShard.apply(this, args)
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
return new Proxy(testGroupsPackage, {
|
|
1150
|
+
get (target, prop, receiver) {
|
|
1151
|
+
if (prop === 'filterForShard') return wrappedFilterForShard
|
|
1152
|
+
return Reflect.get(target, prop, receiver)
|
|
1153
|
+
},
|
|
1154
|
+
})
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1057
1157
|
function deferEfdRetryGroups (testGroups) {
|
|
1058
1158
|
const groupsWithOriginalTests = []
|
|
1059
1159
|
const efdRetryOnlyGroups = []
|
|
@@ -1090,6 +1190,13 @@ function deferEfdRetryGroups (testGroups) {
|
|
|
1090
1190
|
function prepareDispatcherRun (dispatcher, args) {
|
|
1091
1191
|
let testGroups = args[0]
|
|
1092
1192
|
|
|
1193
|
+
for (const group of testGroups) {
|
|
1194
|
+
if (group.tests.length > 0) {
|
|
1195
|
+
hasTestsAssignedToShard = true
|
|
1196
|
+
break
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1093
1200
|
// Filter out disabled tests from testGroups before they get scheduled,
|
|
1094
1201
|
// unless they have attemptToFix (in which case they should still run and be retried)
|
|
1095
1202
|
if (isTestManagementTestsEnabled) {
|
|
@@ -1177,7 +1284,7 @@ function onDispatcherCreateWorker (dispatcher, worker) {
|
|
|
1177
1284
|
videos.push(attachment)
|
|
1178
1285
|
}
|
|
1179
1286
|
})
|
|
1180
|
-
worker.on('testEnd', ({ testId, status, errors, annotations }) => {
|
|
1287
|
+
worker.on('testEnd', ({ testId, status, errors, annotations, duration, expectedStatus, hasNonRetriableError }) => {
|
|
1181
1288
|
const test = getTestByTestId(dispatcher, testId)
|
|
1182
1289
|
if (!test) return
|
|
1183
1290
|
|
|
@@ -1196,6 +1303,10 @@ function onDispatcherCreateWorker (dispatcher, worker) {
|
|
|
1196
1303
|
isTimeout,
|
|
1197
1304
|
shouldCreateTestSpan,
|
|
1198
1305
|
projects,
|
|
1306
|
+
testDuration: duration,
|
|
1307
|
+
testResultStatus: status,
|
|
1308
|
+
expectedStatus,
|
|
1309
|
+
hasNonRetriableError,
|
|
1199
1310
|
}
|
|
1200
1311
|
)
|
|
1201
1312
|
const testResult = test.results.at(-1)
|
|
@@ -1241,10 +1352,16 @@ function onDispatcherCreateWorker (dispatcher, worker) {
|
|
|
1241
1352
|
} else if (test._ddIsAttemptToFix) {
|
|
1242
1353
|
isFinalExecution = !!(test._ddHasPassedAttemptToFixRetries || test._ddHasFailedAttemptToFixRetries)
|
|
1243
1354
|
} else {
|
|
1244
|
-
isFinalExecution = !testWillRetry(test,
|
|
1355
|
+
isFinalExecution = !testWillRetry(test, status, expectedStatus)
|
|
1245
1356
|
}
|
|
1246
1357
|
|
|
1358
|
+
const retryTestId = !isEfdManagedTest && !test._ddIsAttemptToFix && test.retries > 0 ? test.id : undefined
|
|
1359
|
+
const deferFinalStatus = retryTestId !== undefined &&
|
|
1360
|
+
(!isFinalExecution || (isSerialTest(test) && test.results.length <= test.retries))
|
|
1361
|
+
|
|
1247
1362
|
const ddProperties = {
|
|
1363
|
+
_ddRetryTestId: retryTestId,
|
|
1364
|
+
_ddDeferFinalStatus: deferFinalStatus,
|
|
1248
1365
|
_ddIsDisabled: test._ddIsDisabled,
|
|
1249
1366
|
_ddIsQuarantined: test._ddIsQuarantined,
|
|
1250
1367
|
_ddIsAttemptToFix: test._ddIsAttemptToFix,
|
|
@@ -1295,6 +1412,9 @@ function dispatcherHook (dispatcherExport) {
|
|
|
1295
1412
|
test,
|
|
1296
1413
|
annotations: params.annotations,
|
|
1297
1414
|
testStatus: STATUS_TO_TEST_STATUS[testResult.status],
|
|
1415
|
+
testResultStatus: testResult.status,
|
|
1416
|
+
expectedStatus: params.expectedStatus,
|
|
1417
|
+
hasNonRetriableError: params.hasNonRetriableError,
|
|
1298
1418
|
error: testResult.error,
|
|
1299
1419
|
isTimeout,
|
|
1300
1420
|
shouldCreateTestSpan: true,
|
|
@@ -1320,10 +1440,33 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
|
|
|
1320
1440
|
|
|
1321
1441
|
function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
1322
1442
|
// Config parameter is only available from >=1.55.0
|
|
1323
|
-
return async function (config) {
|
|
1443
|
+
return async function (config, options) {
|
|
1444
|
+
// A later run must not inherit ATR settings when configuration fails or the plugin is disabled.
|
|
1445
|
+
isFlakyTestRetriesEnabled = false
|
|
1446
|
+
flakyTestRetriesCount = 0
|
|
1447
|
+
isDynamicAtrEnabled = false
|
|
1448
|
+
dynamicAtrBuckets = undefined
|
|
1449
|
+
if (!libraryConfigurationCh.hasSubscribers) {
|
|
1450
|
+
// Instrumentation hooks still run when the plugin is disabled between runs.
|
|
1451
|
+
isKnownTestsEnabled = false
|
|
1452
|
+
isEarlyFlakeDetectionEnabled = false
|
|
1453
|
+
isTestManagementTestsEnabled = false
|
|
1454
|
+
isImpactedTestsEnabled = false
|
|
1455
|
+
knownTests = {}
|
|
1456
|
+
testManagementTests = {}
|
|
1457
|
+
modifiedFiles = {}
|
|
1458
|
+
return runAllTests.apply(this, arguments)
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
testsToTestStatuses.clear()
|
|
1462
|
+
reportedTestExecutions = new WeakMap()
|
|
1463
|
+
dynamicAtrRetryCountByTestKey.clear()
|
|
1464
|
+
automaticRetryProjects.clear()
|
|
1324
1465
|
reporterError = undefined
|
|
1325
1466
|
hasReporterError = false
|
|
1326
1467
|
playwrightRunSummary = undefined
|
|
1468
|
+
hasTestsAssignedToShard = false
|
|
1469
|
+
hasTestsBeforeSharding = false
|
|
1327
1470
|
let restoreReporterConsoleError
|
|
1328
1471
|
if (satisfies(playwrightVersion, '>=1.60.0') && config?.config) {
|
|
1329
1472
|
const DatadogPlaywrightReporter = require('./playwright-reporter')
|
|
@@ -1333,6 +1476,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1333
1476
|
config.config.reporter.unshift([require.resolve('./playwright-reporter')])
|
|
1334
1477
|
}
|
|
1335
1478
|
}
|
|
1479
|
+
const runnerConfig = getPlaywrightConfig(this)
|
|
1480
|
+
const playwrightConfig = config?.config || runnerConfig.config || runnerConfig
|
|
1336
1481
|
rootDir = getRootDir(this, config)
|
|
1337
1482
|
const projects = getProjectsFromRunner(this, config)
|
|
1338
1483
|
const isFailureScreenshotEnabled = isFailureScreenshotCaptureEnabled(projects)
|
|
@@ -1361,6 +1506,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1361
1506
|
earlyFlakeDetectionFaultyThreshold = libraryConfig.earlyFlakeDetectionFaultyThreshold
|
|
1362
1507
|
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
1363
1508
|
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
1509
|
+
isDynamicAtrEnabled = libraryConfig.isDynamicAtrEnabled
|
|
1510
|
+
dynamicAtrBuckets = libraryConfig.dynamicAtrBuckets
|
|
1364
1511
|
isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
1365
1512
|
testManagementAttemptToFixRetries = libraryConfig.testManagementAttemptToFixRetries
|
|
1366
1513
|
isImpactedTestsEnabled = libraryConfig.isImpactedTestsEnabled
|
|
@@ -1447,11 +1594,23 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1447
1594
|
// ATR and `--retries` are now compatible with Test Management.
|
|
1448
1595
|
// Test Management tests have their retries set to 0 at the test level,
|
|
1449
1596
|
// preventing them from being retried by ATR or `--retries`.
|
|
1450
|
-
const shouldSetATRRetries = isFlakyTestRetriesEnabled &&
|
|
1597
|
+
const shouldSetATRRetries = isFlakyTestRetriesEnabled &&
|
|
1598
|
+
(isDynamicAtrEnabled || flakyTestRetriesCount > 0)
|
|
1599
|
+
const projectsWithAutomaticRetries = []
|
|
1451
1600
|
if (shouldSetATRRetries) {
|
|
1601
|
+
// Dynamic ATR starts at the maximum budget, then narrows each test after
|
|
1602
|
+
// its initial duration is known.
|
|
1603
|
+
const maximumDynamicAtrRetries = dynamicAtrBuckets
|
|
1604
|
+
? Math.max(...dynamicAtrBuckets)
|
|
1605
|
+
: earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
1606
|
+
const atrRetries = isDynamicAtrEnabled
|
|
1607
|
+
? Math.max(1, maximumDynamicAtrRetries)
|
|
1608
|
+
: flakyTestRetriesCount
|
|
1452
1609
|
for (const project of projects) {
|
|
1453
1610
|
if (project.retries === 0) { // Only if it hasn't been set by the user
|
|
1454
|
-
project
|
|
1611
|
+
projectsWithAutomaticRetries.push(project)
|
|
1612
|
+
automaticRetryProjects.add(project)
|
|
1613
|
+
project.retries = atrRetries
|
|
1455
1614
|
}
|
|
1456
1615
|
}
|
|
1457
1616
|
}
|
|
@@ -1475,6 +1634,9 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1475
1634
|
hasReporterError = false
|
|
1476
1635
|
throw error
|
|
1477
1636
|
} finally {
|
|
1637
|
+
for (const project of projectsWithAutomaticRetries) {
|
|
1638
|
+
project.retries = 0
|
|
1639
|
+
}
|
|
1478
1640
|
restoreReporterConsoleError?.()
|
|
1479
1641
|
}
|
|
1480
1642
|
|
|
@@ -1486,6 +1648,14 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1486
1648
|
// there were tests that did not go through `testBegin` or `testEnd`,
|
|
1487
1649
|
// because they were skipped
|
|
1488
1650
|
for (const test of tests) {
|
|
1651
|
+
const lastExecution = reportedTestExecutions.get(test)
|
|
1652
|
+
if (lastExecution) {
|
|
1653
|
+
// Preserve a reported execution whose retry was canceled. Playwright can
|
|
1654
|
+
// also synthesize failed results after hook errors without emitting testEnd.
|
|
1655
|
+
recordFinalTestStatus(test, lastExecution.status, lastExecution.error)
|
|
1656
|
+
finishTestSuiteIfDone(test._requireFile, projects)
|
|
1657
|
+
continue
|
|
1658
|
+
}
|
|
1489
1659
|
const alreadyReported = testsReportedInGenerateSummary.has(test)
|
|
1490
1660
|
const browser = getBrowserNameFromProjects(projects, test)
|
|
1491
1661
|
testBeginHandler(test, browser, !alreadyReported)
|
|
@@ -1493,6 +1663,7 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1493
1663
|
test,
|
|
1494
1664
|
annotations: [],
|
|
1495
1665
|
testStatus: 'skip',
|
|
1666
|
+
testResultStatus: 'skipped',
|
|
1496
1667
|
error: null,
|
|
1497
1668
|
isTimeout: false,
|
|
1498
1669
|
shouldCreateTestSpan: !alreadyReported,
|
|
@@ -1520,8 +1691,30 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1520
1691
|
const finalStatus = hasReporterError
|
|
1521
1692
|
? 'fail'
|
|
1522
1693
|
: (preventedToFail ? 'pass' : STATUS_TO_TEST_STATUS[sessionStatus])
|
|
1694
|
+
const isTestDiscovery = finalStatus === 'pass' &&
|
|
1695
|
+
Boolean(
|
|
1696
|
+
config?.listOnly ||
|
|
1697
|
+
config?.cliListOnly ||
|
|
1698
|
+
runnerConfig.cliListOnly ||
|
|
1699
|
+
runnerConfig._internal?.listOnly ||
|
|
1700
|
+
options?.listMode
|
|
1701
|
+
)
|
|
1702
|
+
const isEmptyShard = Boolean(playwrightConfig.shard) &&
|
|
1703
|
+
hasTestsBeforeSharding &&
|
|
1704
|
+
!hasTestsAssignedToShard &&
|
|
1705
|
+
testsReportedInGenerateSummary.size === 0
|
|
1706
|
+
const hasExecutedTests = [...testsToTestStatuses.values()].some(statuses =>
|
|
1707
|
+
statuses.some(status => status !== 'skip')
|
|
1708
|
+
)
|
|
1709
|
+
const hasSkippedTests = testsToTestStatuses.size > 0 || testsReportedInGenerateSummary.size > 0
|
|
1710
|
+
const testSessionEmptyReason = finalStatus === 'pass' && !hasExecutedTests
|
|
1711
|
+
? (isTestDiscovery
|
|
1712
|
+
? 'test_discovery'
|
|
1713
|
+
: isEmptyShard ? 'zero_test_shard' : hasSkippedTests ? 'all_tests_skipped' : 'zero_tests')
|
|
1714
|
+
: undefined
|
|
1523
1715
|
await getChannelPromise(testSessionFinishCh, {
|
|
1524
|
-
status: finalStatus,
|
|
1716
|
+
status: testSessionEmptyReason ? 'skip' : finalStatus,
|
|
1717
|
+
testSessionEmptyReason,
|
|
1525
1718
|
error: finalizationError,
|
|
1526
1719
|
isEarlyFlakeDetectionEnabled,
|
|
1527
1720
|
isEarlyFlakeDetectionFaulty,
|
|
@@ -1537,6 +1730,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1537
1730
|
playwrightRunSummary = undefined
|
|
1538
1731
|
recordedTestOptimizationExecutions = new Set()
|
|
1539
1732
|
testsReportedInGenerateSummary = new Set()
|
|
1733
|
+
hasTestsAssignedToShard = false
|
|
1734
|
+
hasTestsBeforeSharding = false
|
|
1540
1735
|
efdManagedTestKeys.clear()
|
|
1541
1736
|
efdRetryCountByTestKey.clear()
|
|
1542
1737
|
efdRetryCountRequestsByTestKey.clear()
|
|
@@ -1693,6 +1888,12 @@ dispatcherCreateWorkerCh.subscribe({
|
|
|
1693
1888
|
},
|
|
1694
1889
|
})
|
|
1695
1890
|
|
|
1891
|
+
filterForShardCh.subscribe({
|
|
1892
|
+
start (ctx) {
|
|
1893
|
+
recordTestsBeforeSharding(ctx.arguments.at(-1))
|
|
1894
|
+
},
|
|
1895
|
+
})
|
|
1896
|
+
|
|
1696
1897
|
processHostStartRunnerCh.subscribe({
|
|
1697
1898
|
start (ctx) {
|
|
1698
1899
|
prepareProcessHostStartRunner(ctx.self)
|
|
@@ -1722,6 +1923,14 @@ pageGotoCh.subscribe({
|
|
|
1722
1923
|
},
|
|
1723
1924
|
})
|
|
1724
1925
|
|
|
1926
|
+
// Retry clones exist only after discovery, so persist their original IDs for --last-failed.
|
|
1927
|
+
lastRunTestIdCh.subscribe({
|
|
1928
|
+
end (ctx) {
|
|
1929
|
+
const originalId = originalTestIdsByRetry.get(ctx.arguments[0])
|
|
1930
|
+
if (originalId !== undefined) ctx.result = originalId
|
|
1931
|
+
},
|
|
1932
|
+
})
|
|
1933
|
+
|
|
1725
1934
|
reporterErrorCh.subscribe((error) => {
|
|
1726
1935
|
recordReporterError(error)
|
|
1727
1936
|
})
|
|
@@ -1734,7 +1943,6 @@ reporterRunSummaryCh.subscribe((runSummary) => {
|
|
|
1734
1943
|
* Records a reporter failure even when the reporter throws a falsy value.
|
|
1735
1944
|
*
|
|
1736
1945
|
* @param {unknown} error
|
|
1737
|
-
* @returns {void}
|
|
1738
1946
|
*/
|
|
1739
1947
|
function recordReporterError (error) {
|
|
1740
1948
|
if (hasReporterError) return
|
|
@@ -1756,7 +1964,6 @@ function recordReporterError (error) {
|
|
|
1756
1964
|
* Records a path created by Playwright's automatic screenshot recorder.
|
|
1757
1965
|
*
|
|
1758
1966
|
* @param {object} ctx - Orchestrion context
|
|
1759
|
-
* @returns {void}
|
|
1760
1967
|
*/
|
|
1761
1968
|
function recordAutomaticFailureScreenshotPath (ctx) {
|
|
1762
1969
|
if (isFailureScreenshotUploadEnabled &&
|
|
@@ -1770,7 +1977,6 @@ function recordAutomaticFailureScreenshotPath (ctx) {
|
|
|
1770
1977
|
* Records only the destination used by Playwright's automatic video recorder.
|
|
1771
1978
|
*
|
|
1772
1979
|
* @param {object} ctx - Orchestrion context
|
|
1773
|
-
* @returns {void}
|
|
1774
1980
|
*/
|
|
1775
1981
|
function recordAutomaticFailureVideoPath (ctx) {
|
|
1776
1982
|
const video = ctx.arguments?.[0]
|
|
@@ -1795,6 +2001,12 @@ snapshotRecorderScreenshotPathCh.subscribe({ end: recordAutomaticFailureScreensh
|
|
|
1795
2001
|
saveAutomaticVideoCh.subscribe({ start: recordAutomaticFailureVideoPath })
|
|
1796
2002
|
|
|
1797
2003
|
if (DD_MAJOR < 6) { // <1.38.0 is only supported up to version 5
|
|
2004
|
+
tracingChannel('orchestrion:@playwright/test:Multiplexer_onError').subscribe({
|
|
2005
|
+
start (ctx) {
|
|
2006
|
+
recordReporterError(ctx.arguments[0])
|
|
2007
|
+
},
|
|
2008
|
+
})
|
|
2009
|
+
|
|
1798
2010
|
addHook({
|
|
1799
2011
|
name: '@playwright/test',
|
|
1800
2012
|
file: 'lib/runner.js',
|
|
@@ -1868,6 +2080,12 @@ addHook({
|
|
|
1868
2080
|
versions: ['>=1.38.0 <1.60.0'],
|
|
1869
2081
|
}, (dispatcher) => dispatcherHookNew(dispatcher, dispatcherRunWrapperNew))
|
|
1870
2082
|
|
|
2083
|
+
addHook({
|
|
2084
|
+
name: 'playwright',
|
|
2085
|
+
file: 'lib/runner/testGroups.js',
|
|
2086
|
+
versions: ['>=1.38.0 <1.60.0'],
|
|
2087
|
+
}, testGroupsHook)
|
|
2088
|
+
|
|
1871
2089
|
addHook({
|
|
1872
2090
|
name: 'playwright',
|
|
1873
2091
|
file: 'lib/common/suiteUtils.js',
|
|
@@ -2460,14 +2678,16 @@ function instrumentWorkerMainMethods (workerMain) {
|
|
|
2460
2678
|
})
|
|
2461
2679
|
await Promise.race([ddPropertiesPromise, ddPropertiesTimeoutPromise])
|
|
2462
2680
|
|
|
2681
|
+
const retryTestId = test._ddRetryTestId
|
|
2463
2682
|
const finalStatus = getFinalStatus({
|
|
2464
|
-
|
|
2683
|
+
// Retain a candidate final status while a native retry is possible. The main
|
|
2684
|
+
// process removes it when another execution arrives, or keeps it if retries stop.
|
|
2685
|
+
isFinalExecution: retryTestId !== undefined || test._ddIsFinalExecution,
|
|
2465
2686
|
isDisabled: test._ddIsDisabled,
|
|
2466
2687
|
isQuarantined: test._ddIsQuarantined,
|
|
2467
2688
|
isAtrRetry: test._ddIsAtrRetry,
|
|
2468
2689
|
isEfdManagedTest: test._ddIsEfdManagedTest,
|
|
2469
2690
|
isAttemptToFix: test._ddIsAttemptToFix,
|
|
2470
|
-
hasFailedAllRetries: test._ddHasFailedAllRetries,
|
|
2471
2691
|
hasFailedAttemptToFixRetries: test._ddHasFailedAttemptToFixRetries,
|
|
2472
2692
|
hasPassedAnyEfdAttempt: test._ddHasPassedAnyEfdAttempt,
|
|
2473
2693
|
testStatus: STATUS_TO_TEST_STATUS[status],
|
|
@@ -2475,6 +2695,10 @@ function instrumentWorkerMainMethods (workerMain) {
|
|
|
2475
2695
|
|
|
2476
2696
|
await getChannelPromise(testFinishCh, {
|
|
2477
2697
|
testStatus: STATUS_TO_TEST_STATUS[status],
|
|
2698
|
+
isExpectedFailure: status === 'failed' && testInfo.expectedStatus === 'failed',
|
|
2699
|
+
hasNonRetriableError: testInfo._hasNonRetriableError,
|
|
2700
|
+
retryTestId,
|
|
2701
|
+
deferFinalStatus: test._ddDeferFinalStatus,
|
|
2478
2702
|
steps: steps.filter(step => step.testId === testId),
|
|
2479
2703
|
error,
|
|
2480
2704
|
extraTags: annotationTags,
|