Skip to content

Commit facfd0d

Browse files
perf: remove reporter logs for collapsed tests in run mode (#25632)
Co-authored-by: Emily Rohrbough <[email protected]>
1 parent ae9488f commit facfd0d

File tree

9 files changed

+751
-15
lines changed

9 files changed

+751
-15
lines changed

cli/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ _Released 01/31/2023 (PENDING)_
1212
- Fixed an issue where alternative Microsoft Edge Beta, Canary, and Dev binary versions were not being discovered by Cypress.
1313
Fixes [#25455](https://github.com/cypress-io/cypress/issues/25455).
1414

15+
**Performance:**
16+
17+
- Improved memory consumption in `run` mode by removing reporter logs for successful tests.
18+
Fixes [#25230](https://github.com/cypress-io/cypress/issues/25230).
19+
1520
**Dependency Updates:**
1621

1722
- Upgraded [`underscore.string`](https://github.com/esamattis/underscore.string/blob/HEAD/CHANGELOG.markdown) from `3.3.5` to `3.3.6` to reference rebuilt assets after security patch to fix regular expression DDOS exploit.
18-
Fixed in [#25574](https://github.com/cypress-io/cypress/pull/25574).
1923

2024
## 12.4.1
2125

packages/driver/src/cypress.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ class $Cypress {
551551

552552
// this event is how the reporter knows how to display
553553
// stats and runnable properties such as errors
554-
this.emit('test:after:run', ...args)
554+
this.emit('test:after:run', args[0], this.config('isInteractive'))
555555
this.maybeEmitCypressInCypress('mocha', 'test:after:run', args[0])
556556

557557
if (this.config('isTextTerminal')) {
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import { EventEmitter } from 'events'
2+
import { RootRunnable } from '../../src/runnables/runnables-store'
3+
import { MobxRunnerStore } from '@packages/app/src/store/mobx-runner-store'
4+
5+
let runner: EventEmitter
6+
let runnables: RootRunnable
7+
const { _ } = Cypress
8+
9+
function visitAndRenderReporter (studioEnabled: boolean = false, studioActive: boolean = false) {
10+
cy.fixture('runnables_memory').then((_runnables) => {
11+
runnables = _runnables
12+
})
13+
14+
runner = new EventEmitter()
15+
16+
const runnerStore = new MobxRunnerStore('e2e')
17+
18+
runnerStore.setSpec({
19+
name: 'foo.js',
20+
relative: 'relative/path/to/foo.js',
21+
absolute: '/absolute/path/to/foo.js',
22+
})
23+
24+
cy.visit('/').then((win) => {
25+
win.render({
26+
studioEnabled,
27+
runner,
28+
runnerStore,
29+
})
30+
})
31+
32+
cy.get('.reporter').then(() => {
33+
runner.emit('runnables:ready', runnables)
34+
runner.emit('reporter:start', { studioActive })
35+
})
36+
37+
return runnerStore
38+
}
39+
40+
describe('tests', () => {
41+
beforeEach(() => {
42+
visitAndRenderReporter()
43+
})
44+
45+
context('run mode', () => {
46+
beforeEach(() => {
47+
_.each(runnables.suites, (suite) => {
48+
_.each(suite.tests, (test) => {
49+
runner.emit('test:after:run', test, false)
50+
})
51+
})
52+
})
53+
54+
it('clears logs for a collapsed test', () => {
55+
cy.contains('passed')
56+
.as('passed')
57+
.closest('.runnable')
58+
.should('have.class', 'test')
59+
.find('.runnable-instruments').should('not.exist')
60+
61+
cy.get('@passed').click()
62+
63+
cy.get('@passed')
64+
.parents('.collapsible').first()
65+
.find('.attempt-item').eq(0)
66+
.contains('No commands were issued in this test.')
67+
68+
cy.percySnapshot()
69+
})
70+
71+
it('retains logs for an expanded test', () => {
72+
cy.contains('failed')
73+
.parents('.collapsible').first()
74+
.should('have.class', 'is-open')
75+
.find('.collapsible-content')
76+
.should('be.visible')
77+
78+
cy.contains('failed')
79+
.parents('.collapsible').first()
80+
.find('.attempt-item')
81+
.eq(0)
82+
.find('.attempt-1')
83+
.within(() => {
84+
cy.get('.sessions-container')
85+
cy.get('.runnable-agents-region')
86+
cy.get('.runnable-routes-region')
87+
cy.get('.runnable-commands-region')
88+
})
89+
90+
cy.percySnapshot()
91+
})
92+
93+
it('retains logs for failed attempt and clears logs for passed attempt after retry', () => {
94+
cy.contains('passed after retry')
95+
.parents('.collapsible').first()
96+
.should('not.have.class', 'is-open')
97+
.find('.collapsible-content')
98+
.should('not.exist')
99+
100+
cy.contains('passed after retry').click()
101+
102+
cy.contains('passed after retry')
103+
.parents('.collapsible').first()
104+
.find('.attempt-item').as('attempts')
105+
106+
cy.get('@attempts').eq(0).as('firstAttempt')
107+
.find('.collapsible')
108+
.should('not.have.class', 'is-open')
109+
.find('.collapsible-indicator').should('not.exist')
110+
111+
cy.get('@firstAttempt')
112+
.contains('Attempt 1')
113+
.click()
114+
115+
cy.get('@firstAttempt')
116+
.find('.attempt-1')
117+
.within(() => {
118+
cy.get('.sessions-container')
119+
cy.get('.runnable-agents-region')
120+
cy.get('.runnable-routes-region')
121+
cy.get('.runnable-commands-region')
122+
})
123+
124+
cy.get('@attempts').eq(1).as('secondAttempt')
125+
.find('.collapsible')
126+
.should('have.class', 'is-open')
127+
.find('.collapsible-indicator').should('not.exist')
128+
129+
cy.get('@secondAttempt')
130+
.contains('No commands were issued in this test.')
131+
132+
cy.percySnapshot()
133+
})
134+
135+
it('retains logs for failed attempts', () => {
136+
cy.contains('failed with retries')
137+
.parents('.collapsible').first()
138+
.find('.attempt-item').as('attempts')
139+
140+
cy.get('@attempts').eq(0).as('firstAttempt')
141+
.find('.collapsible')
142+
.should('not.have.class', 'is-open')
143+
.find('.collapsible-indicator').should('not.exist')
144+
145+
cy.get('@firstAttempt')
146+
.contains('Attempt 1')
147+
.click()
148+
149+
cy.get('@firstAttempt')
150+
.find('.attempt-1')
151+
.within(() => {
152+
cy.get('.sessions-container')
153+
cy.get('.runnable-agents-region')
154+
cy.get('.runnable-routes-region')
155+
cy.get('.runnable-commands-region')
156+
})
157+
158+
cy.get('@attempts').eq(1).as('secondAttempt')
159+
.find('.collapsible')
160+
.should('have.class', 'is-open')
161+
.find('.collapsible-content')
162+
.should('be.visible')
163+
164+
cy.get('@secondAttempt')
165+
.find('.attempt-2')
166+
.within(() => {
167+
cy.get('.sessions-container')
168+
cy.get('.runnable-agents-region')
169+
cy.get('.runnable-routes-region')
170+
cy.get('.runnable-commands-region')
171+
})
172+
173+
cy.contains('failed with retries')
174+
.scrollIntoView()
175+
.percySnapshot()
176+
})
177+
})
178+
179+
context('open mode', () => {
180+
beforeEach(() => {
181+
_.each(runnables.suites, (suite) => {
182+
_.each(suite.tests, (test) => {
183+
runner.emit('test:after:run', test, true)
184+
})
185+
})
186+
})
187+
188+
it('retains logs for a collapsed test', () => {
189+
cy.contains('passed')
190+
.as('passed')
191+
.closest('.runnable')
192+
.should('have.class', 'test')
193+
.find('.runnable-instruments').should('not.exist')
194+
195+
cy.get('@passed').click()
196+
197+
cy.get('@passed')
198+
.parents('.collapsible').first()
199+
.find('.attempt-item')
200+
.eq(0)
201+
.find('.attempt-1')
202+
.within(() => {
203+
cy.get('.sessions-container')
204+
cy.get('.runnable-agents-region')
205+
cy.get('.runnable-routes-region')
206+
cy.get('.runnable-commands-region')
207+
})
208+
209+
cy.percySnapshot()
210+
})
211+
212+
it('retains logs for an expanded test', () => {
213+
cy.contains('failed')
214+
.parents('.collapsible').first()
215+
.should('have.class', 'is-open')
216+
.find('.collapsible-content')
217+
.should('be.visible')
218+
219+
cy.contains('failed')
220+
.parents('.collapsible').first()
221+
.find('.attempt-item')
222+
.eq(0)
223+
.find('.attempt-1')
224+
.within(() => {
225+
cy.get('.sessions-container')
226+
cy.get('.runnable-agents-region')
227+
cy.get('.runnable-routes-region')
228+
cy.get('.runnable-commands-region')
229+
})
230+
231+
cy.percySnapshot()
232+
})
233+
})
234+
})

packages/reporter/cypress/e2e/unit/test_model.cy.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ describe('Test model', () => {
101101

102102
command.isLongRunning = true
103103

104-
test.finish({} as UpdatableTestProps)
104+
test.finish({} as UpdatableTestProps, false)
105105
expect(test.isLongRunning).to.be.false
106106
})
107107
})
@@ -282,37 +282,37 @@ describe('Test model', () => {
282282
it('sets the test as inactive', () => {
283283
const test = createTest()
284284

285-
test.finish({} as UpdatableTestProps)
285+
test.finish({} as UpdatableTestProps, false)
286286
expect(test.isActive).to.be.false
287287
})
288288

289289
it('updates the state of the test', () => {
290290
const test = createTest()
291291

292-
test.finish({ state: 'failed' } as UpdatableTestProps)
292+
test.finish({ state: 'failed' } as UpdatableTestProps, false)
293293
expect(test.state).to.equal('failed')
294294
})
295295

296296
it('updates the test err', () => {
297297
const test = createTest()
298298

299-
test.finish({ err: { name: 'SomeError' } as Err } as UpdatableTestProps)
299+
test.finish({ err: { name: 'SomeError' } as Err } as UpdatableTestProps, false)
300300
expect(test.err.name).to.equal('SomeError')
301301
})
302302

303303
it('sets the hook to failed if it exists', () => {
304304
const test = createTest({ hooks: [{ hookId: 'h1', hookName: 'before each' }] })
305305

306306
test.addLog(createCommand({ instrument: 'command' }))
307-
test.finish({ failedFromHookId: 'h1', err: { message: 'foo' } as Err } as UpdatableTestProps)
307+
test.finish({ state: 'failed', failedFromHookId: 'h1', err: { message: 'foo' } as Err } as UpdatableTestProps, false)
308308
expect(test.lastAttempt.hooks[1].failed).to.be.true
309309
})
310310

311311
it('does not throw error if hook does not exist', () => {
312312
const test = createTest()
313313

314314
expect(() => {
315-
test.finish({ hookId: 'h1' } as UpdatableTestProps)
315+
test.finish({ hookId: 'h1' } as UpdatableTestProps, false)
316316
}).not.to.throw()
317317
})
318318
})

0 commit comments

Comments
 (0)