Skip to content

Commit

Permalink
[test optimization] Fix cy.window for multi origin tests (#5185)
Browse files Browse the repository at this point in the history
  • Loading branch information
juan-fernandez authored Feb 3, 2025
1 parent 51a58bc commit 386f4e7
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 32 deletions.
2 changes: 1 addition & 1 deletion integration-tests/cypress-esm-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import cypress from 'cypress'
async function runCypress () {
await cypress.run({
config: {
defaultCommandTimeout: 100,
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
if (process.env.CYPRESS_ENABLE_INCOMPATIBLE_PLUGIN) {
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const cypressFailFast = require('cypress-fail-fast/plugin')
const ddTracePlugin = require('dd-trace/ci/cypress/plugin')

module.exports = {
defaultCommandTimeout: 100,
defaultCommandTimeout: 1000,
e2e: {
setupNodeEvents (on, config) {
if (process.env.CYPRESS_ENABLE_INCOMPATIBLE_PLUGIN) {
Expand Down
57 changes: 56 additions & 1 deletion integration-tests/cypress/cypress.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

const http = require('http')
const { exec } = require('child_process')

const getPort = require('get-port')
Expand Down Expand Up @@ -74,7 +75,7 @@ moduleTypes.forEach(({
describe(`cypress@${version} ${type}`, function () {
this.retries(2)
this.timeout(60000)
let sandbox, cwd, receiver, childProcess, webAppPort
let sandbox, cwd, receiver, childProcess, webAppPort, secondWebAppServer

if (type === 'commonJS') {
testCommand = testCommand(version)
Expand All @@ -91,6 +92,9 @@ moduleTypes.forEach(({
after(async () => {
await sandbox.remove()
await new Promise(resolve => webAppServer.close(resolve))
if (secondWebAppServer) {
await new Promise(resolve => secondWebAppServer.close(resolve))
}
})

beforeEach(async function () {
Expand Down Expand Up @@ -1636,5 +1640,56 @@ moduleTypes.forEach(({
})
})
})

// cy.origin is not available in old versions of Cypress
if (version === 'latest') {
it('does not crash for multi origin tests', async () => {
const {
NODE_OPTIONS, // NODE_OPTIONS dd-trace config does not work with cypress
...restEnvVars
} = getCiVisEvpProxyConfig(receiver.port)

const secondWebAppPort = await getPort()

secondWebAppServer = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html')
res.writeHead(200)
res.end(`
<!DOCTYPE html>
<html>
<div class="hella-world">Hella World</div>
</html>
`)
})

secondWebAppServer.listen(secondWebAppPort)

const specToRun = 'cypress/e2e/multi-origin.js'

childProcess = exec(
version === 'latest' ? testCommand : `${testCommand} --spec ${specToRun}`,
{
cwd,
env: {
...restEnvVars,
CYPRESS_BASE_URL: `http://localhost:${webAppPort}`,
CYPRESS_BASE_URL_SECOND: `http://localhost:${secondWebAppPort}`,
SPEC_PATTERN: specToRun
},
stdio: 'pipe'
}
)

await receiver
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), payloads => {
const events = payloads.flatMap(({ payload }) => payload.events)
assert.equal(events.length, 4)

const test = events.find(event => event.type === 'test').content
assert.equal(test.resource, 'cypress/e2e/multi-origin.js.tests multiple origins')
assert.equal(test.meta[TEST_STATUS], 'pass')
})
})
}
})
})
14 changes: 14 additions & 0 deletions integration-tests/cypress/e2e/multi-origin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable */

it('tests multiple origins', () => {
// Visit first site
cy.visit('/');
cy.get('.hello-world')
.should('have.text', 'Hello World')

// Visit second site
cy.origin(Cypress.env('BASE_URL_SECOND'), () => {
cy.visit('/')
cy.get('.hella-world').should('have.text', 'Hella World')
});
});
65 changes: 36 additions & 29 deletions packages/datadog-plugin-cypress/src/support.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ let isKnownTestsEnabled = false
let knownTestsForSuite = []
let suiteTests = []
let earlyFlakeDetectionNumRetries = 0
// We need to grab the original window as soon as possible,
// in case the test changes the origin. If the test does change the origin,
// any call to `cy.window()` will result in a cross origin error.
let originalWindow

// If the test is using multi domain with cy.origin, trying to access
// window properties will result in a cross origin error.
Expand Down Expand Up @@ -61,6 +65,9 @@ beforeEach(function () {
this.skip()
}
})
cy.window().then(win => {
originalWindow = win
})
})

before(function () {
Expand All @@ -78,39 +85,39 @@ before(function () {
})

after(() => {
cy.window().then(win => {
if (safeGetRum(win)) {
win.dispatchEvent(new Event('beforeunload'))
try {
if (safeGetRum(originalWindow)) {
originalWindow.dispatchEvent(new Event('beforeunload'))
}
})
} catch (e) {
// ignore error. It's usually a multi origin issue.
}
})


afterEach(function () {
cy.window().then(win => {
const currentTest = Cypress.mocha.getRunner().suite.ctx.currentTest
const testInfo = {
testName: currentTest.fullTitle(),
testSuite: Cypress.mocha.getRootSuite().file,
testSuiteAbsolutePath: Cypress.spec && Cypress.spec.absolute,
state: currentTest.state,
error: currentTest.err,
isNew: currentTest._ddIsNew,
isEfdRetry: currentTest._ddIsEfdRetry
}
try {
testInfo.testSourceLine = Cypress.mocha.getRunner().currentRunnable.invocationDetails.line
} catch (e) {}
const currentTest = Cypress.mocha.getRunner().suite.ctx.currentTest
const testInfo = {
testName: currentTest.fullTitle(),
testSuite: Cypress.mocha.getRootSuite().file,
testSuiteAbsolutePath: Cypress.spec && Cypress.spec.absolute,
state: currentTest.state,
error: currentTest.err,
isNew: currentTest._ddIsNew,
isEfdRetry: currentTest._ddIsEfdRetry
}
try {
testInfo.testSourceLine = Cypress.mocha.getRunner().currentRunnable.invocationDetails.line
} catch (e) {}

if (safeGetRum(win)) {
testInfo.isRUMActive = true
}
let coverage
try {
coverage = win.__coverage__
} catch (e) {
// ignore error and continue
}
cy.task('dd:afterEach', { test: testInfo, coverage })
})
if (safeGetRum(originalWindow)) {
testInfo.isRUMActive = true
}
let coverage
try {
coverage = originalWindow.__coverage__
} catch (e) {
// ignore error and continue
}
cy.task('dd:afterEach', { test: testInfo, coverage })
})

0 comments on commit 386f4e7

Please sign in to comment.