Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,21 @@
/integration-tests/config-jest-multiproject.js @DataDog/ci-app-libraries
/integration-tests/config-jest.js @DataDog/ci-app-libraries
/integration-tests/cypress-config.json @DataDog/ci-app-libraries
/integration-tests/cypress-custom-after-hooks.config.js @DataDog/ci-app-libraries
/integration-tests/cypress-custom-after-hooks.config.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-auto-esm.config.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-double-run.js @DataDog/ci-app-libraries
/integration-tests/cypress-double-run.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-esm-config.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-legacy-plugin.config.js @DataDog/ci-app-libraries
/integration-tests/cypress-legacy-plugin.config.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-plain-object-auto.config.js @DataDog/ci-app-libraries
/integration-tests/cypress-plain-object-auto.config.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-plain-object-manual.config.js @DataDog/ci-app-libraries
/integration-tests/cypress-plain-object-manual.config.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-return-config.config.js @DataDog/ci-app-libraries
/integration-tests/cypress-return-config.config.mjs @DataDog/ci-app-libraries
/integration-tests/cypress-typescript.config.ts @DataDog/ci-app-libraries
/integration-tests/cypress.config.js @DataDog/ci-app-libraries
/integration-tests/my-nyc.config.js @DataDog/ci-app-libraries
/integration-tests/playwright.config.js @DataDog/ci-app-libraries
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
'use strict'

module.exports = {
const { defineConfig } = require('cypress')

module.exports = defineConfig({
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
return require('dd-trace/ci/cypress/plugin')(on, config)
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
}
})
11 changes: 11 additions & 0 deletions integration-tests/cypress-auto-esm.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from 'cypress'

export default defineConfig({
defaultCommandTimeout: 1000,
e2e: {
testIsolation: process.env.CYPRESS_TEST_ISOLATION !== 'false',
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
})
36 changes: 36 additions & 0 deletions integration-tests/cypress-custom-after-hooks.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict'

const { defineConfig } = require('cypress')

module.exports = defineConfig({
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
on('after:spec', (spec, results) => {
// eslint-disable-next-line no-console
console.log('[custom:after:spec]', spec.relative, results.stats.passes)
return new Promise((resolve) => {
setTimeout(() => {
// eslint-disable-next-line no-console
console.log('[custom:after:spec:resolved]')
resolve()
}, 50)
})
})
on('after:run', (results) => {
// eslint-disable-next-line no-console
console.log('[custom:after:run]', results.totalPassed)
return new Promise((resolve) => {
setTimeout(() => {
// eslint-disable-next-line no-console
console.log('[custom:after:run:resolved]')
resolve()
}, 50)
})
})
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
})
34 changes: 34 additions & 0 deletions integration-tests/cypress-custom-after-hooks.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defineConfig } from 'cypress'

export default defineConfig({
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
on('after:spec', (spec, results) => {
// eslint-disable-next-line no-console
console.log('[custom:after:spec]', spec.relative, results.stats.passes)
return new Promise((resolve) => {
setTimeout(() => {
// eslint-disable-next-line no-console
console.log('[custom:after:spec:resolved]')
resolve()
}, 50)
})
})
on('after:run', (results) => {
// eslint-disable-next-line no-console
console.log('[custom:after:run]', results.totalPassed)
return new Promise((resolve) => {
setTimeout(() => {
// eslint-disable-next-line no-console
console.log('[custom:after:run:resolved]')
resolve()
}, 50)
})
})
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
})
35 changes: 35 additions & 0 deletions integration-tests/cypress-double-run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict'

// Tests that cypress.run() works twice in the same process (resetRunState).
// Instrumentation works via the default cypress.config.js in the project
// (which uses defineConfig), NOT via the inline config below — Cypress
// does not call setupNodeEvents from inline config objects.
const cypress = require('cypress')

const runOptions = {
config: {
defaultCommandTimeout: 1000,
e2e: {
supportFile: 'cypress/support/e2e.js',
testIsolation: process.env.CYPRESS_TEST_ISOLATION !== 'false',
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
},
}

async function runCypressTwice () {
for (let runNumber = 0; runNumber < 2; runNumber++) {
const results = await cypress.run(runOptions)
if (results.totalFailed !== 0) {
process.exit(1)
}
}
}

runCypressTwice().catch((error) => {
// eslint-disable-next-line no-console
console.error(error)
process.exit(1)
})
25 changes: 25 additions & 0 deletions integration-tests/cypress-double-run.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Tests that cypress.run() works twice in the same process (resetRunState).
// Instrumentation works via the default cypress.config.js in the project
// (which uses defineConfig), NOT via the inline config below — Cypress
// does not call setupNodeEvents from inline config objects.
import cypress from 'cypress'

const runOptions = {
config: {
defaultCommandTimeout: 1000,
e2e: {
supportFile: 'cypress/support/e2e.js',
testIsolation: process.env.CYPRESS_TEST_ISOLATION !== 'false',
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
},
}

for (let runNumber = 0; runNumber < 2; runNumber++) {
const results = await cypress.run(runOptions)
if (results.totalFailed !== 0) {
process.exit(1)
}
}
28 changes: 6 additions & 22 deletions integration-tests/cypress-esm-config.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Programmatic ESM entry point for the 'esm' module type tests.
// Instrumentation works via the default cypress.config.js in the project
// (which uses defineConfig), NOT via the inline setupNodeEvents below —
// Cypress does not call setupNodeEvents from inline config objects.
import cypress from 'cypress'

async function runCypress () {
Expand All @@ -8,38 +12,18 @@ async function runCypress () {
testIsolation: process.env.CYPRESS_TEST_ISOLATION !== 'false',
setupNodeEvents (on, config) {
if (process.env.CYPRESS_ENABLE_INCOMPATIBLE_PLUGIN) {
import('cypress-fail-fast/plugin').then(module => {
return import('cypress-fail-fast/plugin').then(module => {
module.default(on, config)
})
}
if (process.env.CYPRESS_ENABLE_AFTER_RUN_CUSTOM) {
on('after:run', (...args) => {
// do custom stuff
// and call after-run at the end
return import('dd-trace/ci/cypress/after-run').then(module => {
module.default(...args)
})
})
}
if (process.env.CYPRESS_ENABLE_AFTER_SPEC_CUSTOM) {
on('after:spec', (...args) => {
// do custom stuff
// and call after-spec at the end
return import('dd-trace/ci/cypress/after-spec').then(module => {
module.default(...args)
})
})
}
return import('dd-trace/ci/cypress/plugin').then(module => {
return module.default(on, config)
})
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
},
})

if (results.totalFailed !== 0) {
process.exit(1)
}
Expand Down
20 changes: 20 additions & 0 deletions integration-tests/cypress-legacy-plugin.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

// Backwards compatibility config: uses defineConfig AND the old manual plugin.
// When NODE_OPTIONS is set, the instrumentation wraps defineConfig and injects
// setupNodeEvents. The manual plugin call sets cypressPlugin._isInit = true,
// so the instrumentation skips its own registration to avoid double hooks.
const { defineConfig } = require('cypress')
const ddTracePlugin = require('dd-trace/ci/cypress/plugin')

module.exports = defineConfig({
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
return ddTracePlugin(on, config)
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
})
14 changes: 14 additions & 0 deletions integration-tests/cypress-legacy-plugin.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from 'cypress'
import ddTracePlugin from 'dd-trace/ci/cypress/plugin.js'

export default defineConfig({
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
return ddTracePlugin(on, config)
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
},
video: false,
screenshotOnRunFailure: false,
})
13 changes: 13 additions & 0 deletions integration-tests/cypress-plain-object-auto.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict'

// Plain object config without defineConfig and without manual plugin.
// Relies solely on the CLI wrapper to inject setupNodeEvents.
module.exports = {
defaultCommandTimeout: 1000,
e2e: {
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
supportFile: 'cypress/support/e2e.js',
},
video: false,
screenshotOnRunFailure: false,
}
11 changes: 11 additions & 0 deletions integration-tests/cypress-plain-object-auto.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Plain object config without defineConfig and without manual plugin.
// Relies solely on the CLI wrapper to inject setupNodeEvents.
export default {
defaultCommandTimeout: 1000,
e2e: {
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
supportFile: 'cypress/support/e2e.js',
},
video: false,
screenshotOnRunFailure: false,
}
16 changes: 16 additions & 0 deletions integration-tests/cypress-plain-object-manual.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict'

const ddTracePlugin = require('dd-trace/ci/cypress/plugin')

module.exports = {
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
return ddTracePlugin(on, config)
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
supportFile: 'cypress/support/e2e.js',
},
video: false,
screenshotOnRunFailure: false,
}
14 changes: 14 additions & 0 deletions integration-tests/cypress-plain-object-manual.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import ddTracePlugin from 'dd-trace/ci/cypress/plugin.js'

export default {
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
return ddTracePlugin(on, config)
},
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
supportFile: 'cypress/support/e2e.js',
},
video: false,
screenshotOnRunFailure: false,
}
21 changes: 21 additions & 0 deletions integration-tests/cypress-return-config.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict'

const { defineConfig } = require('cypress')

module.exports = defineConfig({
defaultCommandTimeout: 1000,
e2e: {
async setupNodeEvents () {
await new Promise((resolve) => setTimeout(resolve, 50))
return {
env: {
RETURNED_CONFIG_FLAG: 'true',
},
specPattern: 'cypress/e2e/returned-config.cy.js',
}
},
specPattern: 'cypress/e2e/basic-fail.js',
},
video: false,
screenshotOnRunFailure: false,
})
19 changes: 19 additions & 0 deletions integration-tests/cypress-return-config.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig } from 'cypress'

export default defineConfig({
defaultCommandTimeout: 1000,
e2e: {
async setupNodeEvents () {
await new Promise((resolve) => setTimeout(resolve, 50))
return {
env: {
RETURNED_CONFIG_FLAG: 'true',
},
specPattern: 'cypress/e2e/returned-config.cy.js',
}
},
specPattern: 'cypress/e2e/basic-fail.js',
},
video: false,
screenshotOnRunFailure: false,
})
11 changes: 11 additions & 0 deletions integration-tests/cypress-typescript.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from 'cypress'

export default defineConfig({
defaultCommandTimeout: 1000,
e2e: {
specPattern: process.env.SPEC_PATTERN || 'cypress/e2e/**/*.cy.js',
supportFile: 'cypress/support/e2e.js',
},
video: false,
screenshotOnRunFailure: false,
})
Loading
Loading