Skip to content

Commit

Permalink
perf: remove reporter logs for collapsed tests in run mode (#25632)
Browse files Browse the repository at this point in the history
Co-authored-by: Emily Rohrbough <[email protected]>
  • Loading branch information
mschile and emilyrohrbough authored Jan 31, 2023
1 parent ae9488f commit facfd0d
Show file tree
Hide file tree
Showing 9 changed files with 751 additions and 15 deletions.
6 changes: 5 additions & 1 deletion cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ _Released 01/31/2023 (PENDING)_
- Fixed an issue where alternative Microsoft Edge Beta, Canary, and Dev binary versions were not being discovered by Cypress.
Fixes [#25455](https://github.com/cypress-io/cypress/issues/25455).

**Performance:**

- Improved memory consumption in `run` mode by removing reporter logs for successful tests.
Fixes [#25230](https://github.com/cypress-io/cypress/issues/25230).

**Dependency Updates:**

- 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.
Fixed in [#25574](https://github.com/cypress-io/cypress/pull/25574).

## 12.4.1

Expand Down
2 changes: 1 addition & 1 deletion packages/driver/src/cypress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ class $Cypress {

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

if (this.config('isTextTerminal')) {
Expand Down
234 changes: 234 additions & 0 deletions packages/reporter/cypress/e2e/memory.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
import { EventEmitter } from 'events'
import { RootRunnable } from '../../src/runnables/runnables-store'
import { MobxRunnerStore } from '@packages/app/src/store/mobx-runner-store'

let runner: EventEmitter
let runnables: RootRunnable
const { _ } = Cypress

function visitAndRenderReporter (studioEnabled: boolean = false, studioActive: boolean = false) {
cy.fixture('runnables_memory').then((_runnables) => {
runnables = _runnables
})

runner = new EventEmitter()

const runnerStore = new MobxRunnerStore('e2e')

runnerStore.setSpec({
name: 'foo.js',
relative: 'relative/path/to/foo.js',
absolute: '/absolute/path/to/foo.js',
})

cy.visit('/').then((win) => {
win.render({
studioEnabled,
runner,
runnerStore,
})
})

cy.get('.reporter').then(() => {
runner.emit('runnables:ready', runnables)
runner.emit('reporter:start', { studioActive })
})

return runnerStore
}

describe('tests', () => {
beforeEach(() => {
visitAndRenderReporter()
})

context('run mode', () => {
beforeEach(() => {
_.each(runnables.suites, (suite) => {
_.each(suite.tests, (test) => {
runner.emit('test:after:run', test, false)
})
})
})

it('clears logs for a collapsed test', () => {
cy.contains('passed')
.as('passed')
.closest('.runnable')
.should('have.class', 'test')
.find('.runnable-instruments').should('not.exist')

cy.get('@passed').click()

cy.get('@passed')
.parents('.collapsible').first()
.find('.attempt-item').eq(0)
.contains('No commands were issued in this test.')

cy.percySnapshot()
})

it('retains logs for an expanded test', () => {
cy.contains('failed')
.parents('.collapsible').first()
.should('have.class', 'is-open')
.find('.collapsible-content')
.should('be.visible')

cy.contains('failed')
.parents('.collapsible').first()
.find('.attempt-item')
.eq(0)
.find('.attempt-1')
.within(() => {
cy.get('.sessions-container')
cy.get('.runnable-agents-region')
cy.get('.runnable-routes-region')
cy.get('.runnable-commands-region')
})

cy.percySnapshot()
})

it('retains logs for failed attempt and clears logs for passed attempt after retry', () => {
cy.contains('passed after retry')
.parents('.collapsible').first()
.should('not.have.class', 'is-open')
.find('.collapsible-content')
.should('not.exist')

cy.contains('passed after retry').click()

cy.contains('passed after retry')
.parents('.collapsible').first()
.find('.attempt-item').as('attempts')

cy.get('@attempts').eq(0).as('firstAttempt')
.find('.collapsible')
.should('not.have.class', 'is-open')
.find('.collapsible-indicator').should('not.exist')

cy.get('@firstAttempt')
.contains('Attempt 1')
.click()

cy.get('@firstAttempt')
.find('.attempt-1')
.within(() => {
cy.get('.sessions-container')
cy.get('.runnable-agents-region')
cy.get('.runnable-routes-region')
cy.get('.runnable-commands-region')
})

cy.get('@attempts').eq(1).as('secondAttempt')
.find('.collapsible')
.should('have.class', 'is-open')
.find('.collapsible-indicator').should('not.exist')

cy.get('@secondAttempt')
.contains('No commands were issued in this test.')

cy.percySnapshot()
})

it('retains logs for failed attempts', () => {
cy.contains('failed with retries')
.parents('.collapsible').first()
.find('.attempt-item').as('attempts')

cy.get('@attempts').eq(0).as('firstAttempt')
.find('.collapsible')
.should('not.have.class', 'is-open')
.find('.collapsible-indicator').should('not.exist')

cy.get('@firstAttempt')
.contains('Attempt 1')
.click()

cy.get('@firstAttempt')
.find('.attempt-1')
.within(() => {
cy.get('.sessions-container')
cy.get('.runnable-agents-region')
cy.get('.runnable-routes-region')
cy.get('.runnable-commands-region')
})

cy.get('@attempts').eq(1).as('secondAttempt')
.find('.collapsible')
.should('have.class', 'is-open')
.find('.collapsible-content')
.should('be.visible')

cy.get('@secondAttempt')
.find('.attempt-2')
.within(() => {
cy.get('.sessions-container')
cy.get('.runnable-agents-region')
cy.get('.runnable-routes-region')
cy.get('.runnable-commands-region')
})

cy.contains('failed with retries')
.scrollIntoView()
.percySnapshot()
})
})

context('open mode', () => {
beforeEach(() => {
_.each(runnables.suites, (suite) => {
_.each(suite.tests, (test) => {
runner.emit('test:after:run', test, true)
})
})
})

it('retains logs for a collapsed test', () => {
cy.contains('passed')
.as('passed')
.closest('.runnable')
.should('have.class', 'test')
.find('.runnable-instruments').should('not.exist')

cy.get('@passed').click()

cy.get('@passed')
.parents('.collapsible').first()
.find('.attempt-item')
.eq(0)
.find('.attempt-1')
.within(() => {
cy.get('.sessions-container')
cy.get('.runnable-agents-region')
cy.get('.runnable-routes-region')
cy.get('.runnable-commands-region')
})

cy.percySnapshot()
})

it('retains logs for an expanded test', () => {
cy.contains('failed')
.parents('.collapsible').first()
.should('have.class', 'is-open')
.find('.collapsible-content')
.should('be.visible')

cy.contains('failed')
.parents('.collapsible').first()
.find('.attempt-item')
.eq(0)
.find('.attempt-1')
.within(() => {
cy.get('.sessions-container')
cy.get('.runnable-agents-region')
cy.get('.runnable-routes-region')
cy.get('.runnable-commands-region')
})

cy.percySnapshot()
})
})
})
12 changes: 6 additions & 6 deletions packages/reporter/cypress/e2e/unit/test_model.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('Test model', () => {

command.isLongRunning = true

test.finish({} as UpdatableTestProps)
test.finish({} as UpdatableTestProps, false)
expect(test.isLongRunning).to.be.false
})
})
Expand Down Expand Up @@ -282,37 +282,37 @@ describe('Test model', () => {
it('sets the test as inactive', () => {
const test = createTest()

test.finish({} as UpdatableTestProps)
test.finish({} as UpdatableTestProps, false)
expect(test.isActive).to.be.false
})

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

test.finish({ state: 'failed' } as UpdatableTestProps)
test.finish({ state: 'failed' } as UpdatableTestProps, false)
expect(test.state).to.equal('failed')
})

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

test.finish({ err: { name: 'SomeError' } as Err } as UpdatableTestProps)
test.finish({ err: { name: 'SomeError' } as Err } as UpdatableTestProps, false)
expect(test.err.name).to.equal('SomeError')
})

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

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

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

expect(() => {
test.finish({ hookId: 'h1' } as UpdatableTestProps)
test.finish({ hookId: 'h1' } as UpdatableTestProps, false)
}).not.to.throw()
})
})
Expand Down
Loading

5 comments on commit facfd0d

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on facfd0d Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.5.0/linux-arm64/develop-facfd0d88c6060a2179c684e03a699c47ca659c5/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on facfd0d Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.5.0/linux-x64/develop-facfd0d88c6060a2179c684e03a699c47ca659c5/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on facfd0d Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.5.0/darwin-arm64/develop-facfd0d88c6060a2179c684e03a699c47ca659c5/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on facfd0d Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.5.0/darwin-x64/develop-facfd0d88c6060a2179c684e03a699c47ca659c5/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on facfd0d Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.5.0/win32-x64/develop-facfd0d88c6060a2179c684e03a699c47ca659c5/cypress.tgz

Please sign in to comment.