Skip to content

Commit 5fc4b5b

Browse files
feat(test-optimization): support WebdriverIO Jasmine reporting (#9607)
1 parent bbee350 commit 5fc4b5b

24 files changed

Lines changed: 1382 additions & 52 deletions

File tree

integration-tests/ci-visibility-intake.js

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const DEFAULT_TEST_MANAGEMENT_TESTS_RESPONSE_STATUS = 200
4646

4747
class FakeCiVisIntake extends FakeAgent {
4848
#settings = DEFAULT_SETTINGS
49+
#settingsResponseDelayMs = 0
4950
#settingsResponseStatusCode = 200
5051
#settingsResponseStatusCodes = []
5152
#mediaResponseDelayMs = 0
@@ -103,6 +104,16 @@ class FakeCiVisIntake extends FakeAgent {
103104
this.#settings = newSettings
104105
}
105106

107+
/**
108+
* Delays settings responses to exercise initialization ordering.
109+
*
110+
* @param {number} delayMs
111+
* @returns {void}
112+
*/
113+
setSettingsResponseDelay (delayMs) {
114+
this.#settingsResponseDelayMs = delayMs
115+
}
116+
106117
setSettingsResponseCode (statusCode) {
107118
this.#settingsResponseStatusCode = statusCode
108119
}
@@ -280,22 +291,30 @@ class FakeCiVisIntake extends FakeAgent {
280291
'/api/v2/libraries/tests/services/setting',
281292
'/evp_proxy/:version/api/v2/libraries/tests/services/setting',
282293
], (req, res) => {
283-
const settingsResponseStatusCode = this.#settingsResponseStatusCodes.shift() ??
284-
this.#settingsResponseStatusCode
285-
res.status(settingsResponseStatusCode)
286-
if (settingsResponseStatusCode >= 200 && settingsResponseStatusCode < 300) {
287-
res.send(JSON.stringify({
288-
data: {
289-
attributes: this.#settings,
290-
},
291-
}))
294+
const respond = () => {
295+
const settingsResponseStatusCode = this.#settingsResponseStatusCodes.shift() ??
296+
this.#settingsResponseStatusCode
297+
res.status(settingsResponseStatusCode)
298+
if (settingsResponseStatusCode >= 200 && settingsResponseStatusCode < 300) {
299+
res.send(JSON.stringify({
300+
data: {
301+
attributes: this.#settings,
302+
},
303+
}))
304+
} else {
305+
res.send(JSON.stringify({ errors: ['error'] }))
306+
}
307+
this.emit('message', {
308+
headers: req.headers,
309+
url: req.url,
310+
})
311+
}
312+
313+
if (this.#settingsResponseDelayMs > 0) {
314+
setTimeout(respond, this.#settingsResponseDelayMs)
292315
} else {
293-
res.send(JSON.stringify({ errors: ['error'] }))
316+
respond()
294317
}
295-
this.emit('message', {
296-
headers: req.headers,
297-
url: req.url,
298-
})
299318
})
300319

301320
app.post([
@@ -417,6 +436,7 @@ class FakeCiVisIntake extends FakeAgent {
417436

418437
stop () {
419438
this.#settings = DEFAULT_SETTINGS
439+
this.#settingsResponseDelayMs = 0
420440
this.#settingsResponseStatusCode = 200
421441
this.#settingsResponseStatusCodes = []
422442
this.#suitesToSkip = DEFAULT_SUITES_TO_SKIP
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
'use strict'
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict'
2+
3+
const tracer = require('dd-trace')
4+
5+
const assert = require('node:assert/strict')
6+
7+
describe('WebdriverIO Jasmine afterAll failure', () => {
8+
// eslint-disable-next-line no-undef -- Jasmine exposes afterAll through WebdriverIO.
9+
afterAll(() => {
10+
throw new Error('expected WebdriverIO Jasmine afterAll failure')
11+
})
12+
13+
it('passes before afterAll fails', () => {
14+
assert.ok(tracer.scope().active())
15+
})
16+
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict'
2+
3+
// eslint-disable-next-line no-undef -- Jasmine exposes afterAll through WebdriverIO.
4+
afterAll(() => {
5+
throw new Error('expected WebdriverIO Jasmine global afterAll failure')
6+
})
7+
8+
describe('Jasmine global afterAll failure', () => {
9+
it('passes before the global hook fails', () => {})
10+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict'
2+
3+
const tracer = require('dd-trace')
4+
5+
const assert = require('node:assert/strict')
6+
7+
describe('WebdriverIO Jasmine per-test hooks', () => {
8+
let testSpan
9+
10+
beforeEach(() => {
11+
testSpan = tracer.scope().active()
12+
13+
assert.ok(testSpan)
14+
testSpan.setTag('test.webdriverio.jasmine.before-each', 'active')
15+
})
16+
17+
afterEach(() => {
18+
const activeSpan = tracer.scope().active()
19+
20+
assert.strictEqual(activeSpan, testSpan)
21+
activeSpan.setTag('test.webdriverio.jasmine.after-each', 'active')
22+
})
23+
24+
it('keeps the test span active', () => {
25+
assert.strictEqual(tracer.scope().active(), testSpan)
26+
})
27+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict'
2+
3+
const tracer = require('dd-trace')
4+
5+
const assert = require('node:assert/strict')
6+
7+
describe('WebdriverIO Jasmine statuses', () => {
8+
it('reports a passing test with an active span', () => {
9+
const activeSpan = tracer.scope().active()
10+
11+
assert.ok(activeSpan)
12+
activeSpan.setTag('test.webdriverio.worker', 'jasmine')
13+
})
14+
15+
it('reports a failing test', () => {
16+
assert.fail('expected WebdriverIO Jasmine integration failure')
17+
})
18+
19+
// eslint-disable-next-line mocha/no-pending-tests -- this fixture verifies skipped-test reporting.
20+
xit('reports a skipped test', () => {})
21+
})

integration-tests/webdriverio/fixtures/wdio.conf.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const scenario = process.env.WEBDRIVERIO_SCENARIO || 'parallel'
4+
const framework = process.env.WEBDRIVERIO_FRAMEWORK || 'mocha'
45

56
const baseConfig = {
67
runner: 'local',
@@ -18,8 +19,12 @@ const baseConfig = {
1819
path: '/',
1920
connectionRetryCount: 0,
2021
services: [],
21-
framework: 'mocha',
22+
framework,
2223
reporters: [],
24+
jasmineOpts: {
25+
defaultTimeoutInterval: 10_000,
26+
random: false,
27+
},
2328
mochaOpts: {
2429
ui: 'bdd',
2530
timeout: 10_000,
@@ -100,6 +105,13 @@ const scenarioConfig = {
100105
'./second.e2e.js',
101106
]],
102107
},
108+
groupedEmpty: {
109+
maxInstances: 1,
110+
specs: [[
111+
'./empty.e2e.js',
112+
'./first.e2e.js',
113+
]],
114+
},
103115
hookFailure: {
104116
maxInstances: 1,
105117
specs: [[
@@ -111,6 +123,29 @@ const scenarioConfig = {
111123
maxInstances: 1,
112124
specs: ['./impacted.e2e.js'],
113125
},
126+
jasmineStatuses: {
127+
maxInstances: 1,
128+
specs: ['./jasmine-statuses.e2e.js'],
129+
},
130+
jasmineAfterAllFailure: {
131+
maxInstances: 1,
132+
specs: ['./jasmine-after-all-fail.e2e.js'],
133+
},
134+
jasmineDelayedSettings: {
135+
maxInstances: 1,
136+
specs: ['./first.e2e.js'],
137+
},
138+
jasmineGlobalAfterAllFailure: {
139+
maxInstances: 1,
140+
specs: [[
141+
'./jasmine-global-after-all-fail.e2e.js',
142+
'./first.e2e.js',
143+
]],
144+
},
145+
jasmineHooks: {
146+
maxInstances: 1,
147+
specs: ['./jasmine-hooks.e2e.js'],
148+
},
114149
loadFailure: {
115150
maxInstances: 1,
116151
specs: ['./load-fail.e2e.js'],

0 commit comments

Comments
 (0)