[test optimization] Refactor cypress as instrumentation#7829
[test optimization] Refactor cypress as instrumentation#7829juan-fernandez wants to merge 15 commits intomasterfrom
cypress as instrumentation#7829Conversation
Overall package sizeSelf size: 5.44 MB Dependency sizes| name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 3.0.0 | 81.15 kB | 815.98 kB | | dc-polyfill | 0.1.10 | 26.73 kB | 26.73 kB |🤖 This report was automatically generated by heaviest-objects-in-the-universe |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #7829 +/- ##
==========================================
- Coverage 74.26% 74.01% -0.25%
==========================================
Files 765 766 +1
Lines 35786 35923 +137
==========================================
+ Hits 26575 26589 +14
- Misses 9211 9334 +123 Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
✅ Tests 🎉 All green!❄️ No new flaky tests detected 🎯 Code Coverage (details) 🔗 Commit SHA: 64bd146 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback! |
BenchmarksBenchmark execution time: 2026-03-30 13:54:00 Comparing candidate commit ba4b9ae in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 227 metrics, 33 unstable metrics. |
cypress as instrumentationcypress as instrumentation
… test On CI, early-flush payloads may contain test events without per-level metadata keys, causing the metadata?.test filter to exclude them. Use a simpler event.type === 'test' filter instead. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…c chaining - Support file injection uses a temp wrapper in os.tmpdir() with absolute paths instead of mutating the user's support file on disk. Cleaned up via after:run handler. - cypressPlugin.init() Promise is now properly returned so Cypress awaits async config mutations (retries, library config). - User's after:spec/after:run handlers are chained with dd-trace's, awaiting each in sequence (supports async handlers returning Promises). - Also wraps cypress.open() for interactive mode. - Handles async setupNodeEvents (Promise return) from user code. - Adds integration test verifying support file is not modified and wrapper is cleaned up. - Adds CODEOWNERS for new config files. - Removes stale Module._load approach (overwritten by dd-trace's ritm). - Updates ESM config to plain object (wrapped via cypress.run hook). - Fixes legacy plugin config comment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove `ensureCiVisibilityTracer` duplication — `ci/init` now initializes the tracer in Cypress CLI/Electron processes (removed `isCliTool` skip) - Remove `esmFirst` flag — `defineConfig` shimmer works for ESM configs via ritm because Cypress internally transpiles .mjs to CJS - Remove `rewriteCliNodeOptions` — config wrapper now lives next to the original file instead of in os.tmpdir(), so module resolution works naturally - Remove `run`/`open` shimming — inline config wrapping was belt-and-suspenders since Cypress never calls setupNodeEvents from inline config - Always use ESM (.mjs) wrappers for both config and support files — ESM can import both CJS and ESM, so it works regardless of "type":"module" - Fix CLI hook file paths: lib/exec/run.js → dist/exec/run.js (actual Cypress package structure), handle .default on transpiled module exports - Add ESM variants for all integration tests so every scenario runs for both CJS and ESM module types - Make returned-config test async to cover the promise branch in wrapSetupNodeEvents Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hook both lib/exec/{run,open}.js (Cypress 10-14) and dist/exec/{run,open}.js
(Cypress 15+) so the CLI wrapper fires across all supported versions
- Add ESM variants of all integration test configs and scripts so every
scenario runs for both CJS and ESM module types
- Add plain-object auto-instrumentation test (no defineConfig, no manual plugin)
- Fix ESM config imports to include .js extension for dd-trace/ci/cypress/plugin
- Revert ci/init.js to master (no isCliTool/ensureCiVisibilityTracer needed)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve default config file when no --config-file is passed, enabling
plain-object configs (without defineConfig) in the standard cypress run flow
- Skip .ts config files — Cypress transpiles them internally, ESM wrapper can't
import .ts directly
- Hook both lib/exec/{run,open}.js (Cypress 10-14) and dist/exec/{run,open}.js
(Cypress 15+) so the CLI wrapper fires across all supported versions
- Respect configFile: false — don't override with a resolved default
- Add comments to programmatic test scripts clarifying that instrumentation
works via the default config file, not inline configs
- Add TypeScript config regression test
- Add plain-object default config (no --config-file) regression test
- Fix ESM config imports to include .js extension for dd-trace/ci/cypress/plugin
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f9b4c02 to
92b02d4
Compare
What does this PR do?
Auto-instrument Cypress >=10 so users can run
NODE_OPTIONS='-r dd-trace/ci/init' cypress runwithout manual plugin setup. Two complementary mechanisms:defineConfigshimmer — wrapsdefineConfig()viaaddHookonrequire('cypress'). Covers CJS configs, TypeScript configs, and programmaticcypress.run().start()hook — interceptslib/exec/run.js(Cypress 10-14) anddist/exec/run.js(Cypress 15+) to create a temp ESM wrapper around the config file. Covers plain-object configs (nodefineConfig) and ESM.mjsconfigs.Support file is auto-injected via a temp wrapper in
os.tmpdir()(cleaned up after run). Userafter:spec/after:runhandlers are chained with dd-trace's.Motivation
Align Cypress with jest, mocha, vitest, playwright, and cucumber — just set
NODE_OPTIONSand run.Changes
cypress-config.js(new) — config wrapping logic:wrapConfig,wrapSetupNodeEvents,registerDdTraceHooks, handler chaining, support file injection,mergeReturnedConfigfor async setupNodeEvents return values, CLI config file wrapper (always ESM.mjs— works for both CJS and ESM originals). Skips.tsfiles (Cypress transpiles them internally).cypress.js—defineConfigshimmer + CLIstart()hooks forlib/exec/anddist/exec/pathscypress-plugin.js—resetRunState()for programmatic multi-run support,_isInit = falseinafterRunci/cypress/wrap-config.js— CJS bridge for the ESM wrapper to importwrapConfighooks.js— no special flags needed (removedesmFirst)ci/init.js— unchanged from masterBackwards compatible
dd-trace/ci/cypress/plugin) still works —_isInitflag prevents double-hookingcypress <10unaffected (no auto-instrumentation)DD_CONFIG_WRAPPEDsymbol prevents double-wrappingTest coverage
9 integration test scenarios, each running for both CJS and ESM module types across Cypress 10.2.0, 14.5.4, and latest:
_isInitskip.mjscypress.run()called twice —resetRunStatemodule.exports = {}+ manual plugin--config-fileplain object, no defineConfig--config-file, default config is plain object.tsconfig — skipped by CLI wrapper, handled by defineConfig shimmersetupNodeEventsreturning partial configafter:spec/after:runchained with dd-trace