Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7d615f0
fix: render command log in an isolated iframe to prevent renderer crash
mschile Jul 7, 2026
ceb452c
test: scope cy-in-cy reporter queries to the command-log iframe
mschile Jul 7, 2026
dec579e
fix: keep reporter panel resizable now that the command log is an iframe
mschile Jul 8, 2026
b7f07ce
fix: keep the runnable options popover visible in narrow reporter panels
mschile Jul 8, 2026
64a1dbf
fix: stop Tailwind's container class from clamping the command log width
mschile Jul 8, 2026
64ed176
chore: move renderer crash changelog entry under Performance
mschile Jul 8, 2026
13f1780
Merge branch 'develop' into mschile/busy-poincare-345146
mschile Jul 8, 2026
91c9c0a
fix: mount the reporter before its stylesheets finish loading
mschile Jul 8, 2026
71554c1
Merge branch 'mschile/busy-poincare-345146' of https://github.com/cyp…
mschile Jul 8, 2026
a1fab97
fix: cap the reporter reveal wait and scope session expander clicks
mschile Jul 8, 2026
5c45eb3
fix: unmount the iframe React root before falling back to inline rend…
mschile Jul 8, 2026
4e3c067
fix: dismiss the options popover from interactions in either document
mschile Jul 8, 2026
b5b7dd3
test: point driver and reporter integration helpers at the command-lo…
mschile Jul 8, 2026
26435ec
test: scope reporter queries missed in the iframe migration
mschile Jul 8, 2026
a9a01b5
test: point system-test fixture reporter queries at the command-log i…
mschile Jul 8, 2026
79700b9
fix: identify the Firefox BiDi AUT frame by window.name
mschile Jul 8, 2026
d054625
test: stub window.name for the Firefox BiDi AUT-frame identification
mschile Jul 8, 2026
43fc539
test: point Angular zonejs reporter queries at the command-log iframe
mschile Jul 8, 2026
51b63ff
Merge branch 'develop' into mschile/busy-poincare-345146
mschile Jul 9, 2026
1fcfdbb
test: apply Percy element overrides inside the reporter iframe
mschile Jul 9, 2026
0edd8de
Merge branch 'develop' into mschile/busy-poincare-345146
mschile Jul 11, 2026
1404800
fix: mount the reporter iframe into a container instead of document.body
mschile Jul 13, 2026
c17c7c0
fix: load the reporter iframe stylesheets from absolute URLs
mschile Jul 13, 2026
1aa5bca
test: open the specs list via the reporter toggle instead of a keystroke
mschile Jul 14, 2026
0be5e19
test: keep the f shortcut coverage and wait for reporter readiness
mschile Jul 14, 2026
d29d168
refactor: address reporter-iframe PR review feedback
mschile Jul 16, 2026
d3cc1c9
Merge branch 'develop' into mschile/busy-poincare-345146
mschile Jul 16, 2026
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
1 change: 1 addition & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

**Performance:**

- Fixed an issue where the browser's renderer process could crash (`We detected that the Chrome Renderer process just crashed`) when the application under test triggered a `ResizeObserver` loop while the command log was visible. Fixes [#33962](https://github.com/cypress-io/cypress/issues/33962) and [#34218](https://github.com/cypress-io/cypress/issues/34218).
- Fixed a regression in [14.0.0](#14-0-0) where each message sent from the Cypress server to a Chromium-based browser (including Electron) leaked a small amount of browser memory until the end of the spec. During long, command- or network-heavy specs, this buildup could crash the browser (`We detected that the Chrome Renderer process just crashed`). Fixes [#34226](https://github.com/cypress-io/cypress/issues/34226).
- Fixed an issue where each [`cy.press()`](https://on.cypress.io/press) call in Chromium-based browsers retained a small amount of renderer memory for the remainder of the spec file, which could contribute to memory growth in specs with many `cy.press()` calls. Addressed in [#34240](https://github.com/cypress-io/cypress/pull/34240).

Expand Down
14 changes: 7 additions & 7 deletions packages/app/cypress/e2e/cypress-in-cypress-component.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
cy.specsPageIsVisible()
cy.contains('TestComponent.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test component')

cy.findByTestId('aut-url-input').should('have.prop', 'readOnly', true)
cy.findByTestId('select-browser').click()
Expand All @@ -30,7 +30,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
cy.get('body').click()

// Temporarily removed from CT since it doesn't work. Invert this assertion when completing https://github.com/cypress-io/cypress/issues/24549
cy.get('.hook-open-in-ide').should('not.exist')
cy.reporter().find('.hook-open-in-ide').should('not.exist')

cy.get('#unified-runner').should('have.attr', 'style', 'width: 500px; height: 500px; transform: scale(1); position: absolute; margin-left: 225px;')
})
Expand All @@ -40,23 +40,23 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
cy.specsPageIsVisible()
cy.contains('TestComponent.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test component')

// go to Settings page and back to spec runner
cy.contains('a', 'Settings').click()
cy.contains(defaultMessages.settingsPage.device.title).should('be.visible')
cy.contains('a', 'Specs').click()
cy.contains('TestComponent.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test component')

// go to Runs page and back to spec runner
cy.contains('a', 'Runs').click()
cy.contains(defaultMessages.runs.connect.title).should('be.visible')
cy.contains('a', 'Specs').click()
cy.contains('TestComponent.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test component')
})

// TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23159
Expand Down Expand Up @@ -87,7 +87,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:

cy.visitApp(`/specs/runner?file=${goodFilePath}`)

cy.contains('renders the test component').should('be.visible')
cy.reporter().contains('renders the test component').should('be.visible')

cy.withCtx((ctx, o) => {
ctx.actions.project.setSpecs(ctx.project.specs.filter((spec) => !spec.absolute.includes(o.path)))
Expand All @@ -107,7 +107,7 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
cy.specsPageIsVisible()
cy.contains('TestComponent.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test component')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test component')

cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.actions.browser, 'setActiveBrowserById')
Expand Down
43 changes: 24 additions & 19 deletions packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.contains('dom-content.spec').click()
cy.waitForSpecToFinish()

cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.findByTestId('aut-url').should('be.visible')
cy.findByTestId('select-browser').click()

Expand All @@ -34,7 +34,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.contains('Canary').should('be.hidden')
cy.get('body').click()

cy.get('.hook-open-in-ide').should('exist')
cy.reporter().find('.hook-open-in-ide').should('exist')

cy.get('#unified-runner').then((el) => {
expect(el[0].getAttribute('style')).to.match(/width: 1000px; height: 660px; transform: scale\(0.85\); position: absolute; margin-left: -25px;/)
Expand All @@ -51,7 +51,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.contains('dom-content.spec').click()
cy.waitForSpecToFinish()

cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.findByTestId('aut-url').should('be.visible')

cy.get('#unified-runner').then((el) => {
Expand All @@ -66,23 +66,23 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.specsPageIsVisible()
cy.contains('dom-content.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test content')

// go to Settings page and back to spec runner
cy.contains('a', 'Settings').click()
cy.contains(defaultMessages.settingsPage.device.title).should('be.visible')
cy.contains('a', 'Specs').click()
cy.contains('dom-content.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test content')

// go to Runs page and back to spec runner
cy.contains('a', 'Runs').click()
cy.contains(defaultMessages.runs.connect.title).should('be.visible')
cy.contains('a', 'Specs').click()
cy.contains('dom-content.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test content')
})

it('redirects to the specs list with error if a spec is not found when navigating', () => {
Expand Down Expand Up @@ -112,7 +112,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:

cy.visit(`http://localhost:4455/__/#/specs/runner?file=${goodFilePath}`)

cy.contains('Dom Content').should('be.visible')
cy.reporter().contains('Dom Content').should('be.visible')

cy.withCtx((ctx, o) => {
ctx.actions.project.setSpecs(ctx.project.specs.filter((spec) => !spec.absolute.includes(o.path)))
Expand All @@ -133,7 +133,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.contains('blank-contents.spec')
.click()

cy.get('[data-model-state="passed"]').should('contain', 'renders the blank page')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the blank page')
})

it('shows a compilation error with a malformed spec', { viewportHeight: 596, viewportWidth: 1000 }, () => {
Expand All @@ -149,7 +149,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.contains('bad-spec.spec')
.click()

cy.contains('No tests found').should('be.visible')
cy.reporter().contains('No tests found').should('be.visible')

cy.contains('SyntaxError')
.should('be.visible')
Expand All @@ -171,7 +171,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.contains('blank-contents.spec')
.click()

cy.get('[data-model-state="failed"]').should('contain', 'renders the blank page')
cy.reporter().find('[data-model-state="failed"]').should('contain', 'renders the blank page')
// cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435
})

Expand All @@ -183,7 +183,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.specsPageIsVisible()
cy.contains('dom-content.spec').click()

cy.get('.toggle-specs-wrapper').click()
cy.reporter().find('.toggle-specs-wrapper').click()

cy.get('#unified-runner').then((el) => {
// CSS properties are calculated over inline styles, which means we get a close representation
Expand All @@ -198,45 +198,50 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.specsPageIsVisible()
cy.contains('withFailure.spec').click()

cy.get('[data-cy="runnable-header"]').should('be.visible')
cy.get('body').type('f')
cy.reporter().find('[data-cy="runnable-header"]').should('be.visible')
// this test switches specs mid-run, so we can't wait for the run to finish
// before opening the specs list. Click the reporter's toggle (its onClick is
// bound at render) rather than pressing `f`, whose keydown handler binds in a
// passive effect that can lag the iframe reporter's mount on slower machines.
// The `f` shortcut itself is covered by reporter_header.cy.ts.
cy.reporter().find('.toggle-specs-wrapper').click()
cy.contains('Search specs')
cy.contains('withWait.spec').click()
cy.waitForSpecToFinish()

cy.get('.passed > .num').should('contain', 4)
cy.get('.failed > .num').should('not.contain', 1)
cy.reporter().find('.passed > .num').should('contain', 4)
cy.reporter().find('.failed > .num').should('not.contain', 1)
})

it('executes a test, navigates back to the spec list, creates a new spec, and runs the new spec', () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('dom-content.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'renders the test content')
cy.contains('a', 'Specs').click()
cy.withCtx(async (ctx, o) => {
await ctx.actions.file.writeFileInProject(o.path, `describe('Simple Test', () => { it('true is true', () => { expect(true).to.be.true }) })`)
}, { path: getPathForPlatform('cypress/e2e/new-file.spec.js') })

cy.contains('new-file.spec').click()
cy.waitForSpecToFinish()
cy.get('[data-model-state="passed"]').should('contain', 'expected true to be true')
cy.reporter().find('[data-model-state="passed"]').should('contain', 'expected true to be true')
})

describe('accessibility', () => {
it('has no axe violations in specs list panel', () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('withFailure.spec').click()
cy.get('button[aria-controls="reporter-inline-specs-list"]').click()
cy.reporter().find('button[aria-controls="reporter-inline-specs-list"]').click()
})

it('has no axe violations in reporter panel', () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('withFailure.spec').click()
cy.get('button[aria-controls="reporter-inline-specs-list"]').click()
cy.reporter().find('button[aria-controls="reporter-inline-specs-list"]').click()
})
})
})
12 changes: 4 additions & 8 deletions packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
cy.findByTestId('aut-url').should('be.visible')
cy.findByTestId('playground-activator').should('not.exist')

cy.findByLabelText('Stats').within(() => {
cy.get('.passed .num', { timeout: 10000 }).should('have.text', '1')
})
cy.reporter().find('[aria-label="Stats"] .passed .num', { timeout: 10000 }).should('have.text', '1')

// confirm expected content is rendered
cy.contains('1000x660').should('be.visible')
Expand All @@ -43,9 +41,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
cy.findByTestId('aut-url').contains('URL navigation disabled in component testing').should('be.visible')
cy.findByTestId('playground-activator').should('not.exist')

cy.findByLabelText('Stats').within(() => {
cy.get('.passed .num', { timeout: 10000 }).should('have.text', '1')
})
cy.reporter().find('[aria-label="Stats"] .passed .num', { timeout: 10000 }).should('have.text', '1')

// confirm expected content is rendered
cy.contains('500x500').should('be.visible')
Expand Down Expand Up @@ -76,7 +72,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
cy.visitApp(`/specs/runner?file=cypress/e2e/dom-content.spec.js&${CY_IN_CY_SIMULATE_RUN_MODE}`)

cy.contains('http://localhost:4455/cypress/e2e/dom-content.html').should('be.visible')
cy.findByLabelText('Stats').should('not.exist')
cy.get('#reporter-frame').should('not.exist')
cy.findByTestId('specs-list-panel').should('not.be.visible')
cy.findByTestId('reporter-panel').should('not.be.visible')
cy.findByTestId('sidebar').should('not.exist')
Expand All @@ -100,7 +96,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
cy.visitApp(`/specs/runner?file=cypress/e2e/dom-content.spec.js&${CY_IN_CY_SIMULATE_RUN_MODE}`)

cy.contains('http://localhost:4455/cypress/e2e/dom-content.html').should('not.exist')
cy.findByLabelText('Stats').should('not.exist')
cy.get('#reporter-frame').should('not.exist')
cy.findByTestId('specs-list-panel').should('not.be.visible')
cy.findByTestId('reporter-panel').should('not.be.visible')
cy.findByTestId('sidebar').should('not.exist')
Expand Down
8 changes: 4 additions & 4 deletions packages/app/cypress/e2e/cypress-in-cypress.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
// validate that the width we set in `withCtx` above is the starting point
cy.get(`[data-cy="reporter-panel"]`).invoke('outerWidth').should('eq', 800)

cy.findByTestId('toggle-specs-button').click({ force: true })
cy.reporter().find('[data-cy="toggle-specs-button"]').click({ force: true })

// this tooltip text confirms specs list is open
cy.contains('Collapse Specs List')
cy.reporter().contains('Collapse Specs List')

// we will move the right-hand handle of the Reporter
// to these positions from the left of the screen
Expand Down Expand Up @@ -200,7 +200,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
cy.contains('dom-content.spec').click()

cy.findByTestId('aut-url-input').invoke('val').should('contain', 'http://localhost:4455/cypress/e2e/dom-content.html')
cy.findByLabelText('Stats').should('not.exist')
cy.get('#reporter-frame').should('not.exist')
cy.findByTestId('specs-list-panel').should('not.be.visible')
cy.findByTestId('reporter-panel').should('not.be.visible')
cy.findByTestId('sidebar').should('be.visible')
Expand Down Expand Up @@ -380,7 +380,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
)
})

cy.contains('Dom Content').should('be.visible')
cy.reporter().contains('Dom Content').should('be.visible')
})
})
})
18 changes: 9 additions & 9 deletions packages/app/cypress/e2e/cypress-origin-communicator.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('Cypress In Cypress Origin Communicator', { defaultCommandTimeout: 1000
cy.waitForSpecToFinish()
trackRemoveAllListenersOnAllCypressInstances()

cy.get('[aria-controls="reporter-inline-specs-list"]').type('{enter}')
cy.reporter().find('[aria-controls="reporter-inline-specs-list"]').click()
cy.get('[data-cy="spec-row-item"]').contains('123').click()
cy.waitForSpecToFinish()

Expand Down Expand Up @@ -149,19 +149,19 @@ describe('Cypress In Cypress Origin Communicator', { defaultCommandTimeout: 1000
cy.contains('simple_origin.cy').click()
cy.waitForSpecToFinish()

cy.get('.passed > .num').should('contain', 1)
cy.reporter().find('.passed > .num').should('contain', 1)
// make sure duplicate logs are not present
cy.get('.command-name-origin').find('.command-name-log').should('have.length', 2)
cy.reporter().find('.command-name-origin').find('.command-name-log').should('have.length', 2)

cy.findByTestId('sidebar-link-specs-page').click()
cy.location('hash').should('include', '/specs')

cy.contains('simple_origin.cy').click()
cy.waitForSpecToFinish()

cy.get('.passed > .num').should('contain', 1)
cy.reporter().find('.passed > .num').should('contain', 1)
// make sure duplicate logs are not present
cy.get('.command-name-origin').find('.command-name-log').should('have.length', 2)
cy.reporter().find('.command-name-origin').find('.command-name-log').should('have.length', 2)
})

it('passes upon test reload mid test execution', () => {
Expand All @@ -176,9 +176,9 @@ describe('Cypress In Cypress Origin Communicator', { defaultCommandTimeout: 1000
cy.contains('simple_origin.cy').click()
cy.waitForSpecToFinish()

cy.get('.passed > .num').should('contain', 1)
cy.reporter().find('.passed > .num').should('contain', 1)
// make sure duplicate logs are not present
cy.get('.command-name-origin').find('.command-name-log').should('have.length', 2)
cy.reporter().find('.command-name-origin').find('.command-name-log').should('have.length', 2)

cy.withCtx(async (ctx) => {
const indexPath = ctx.path.join('cypress', 'e2e', 'origin', 'simple_origin.cy.js')
Expand All @@ -191,9 +191,9 @@ describe('Cypress In Cypress Origin Communicator', { defaultCommandTimeout: 1000

cy.waitForSpecToFinish()

cy.get('.passed > .num').should('contain', 1)
cy.reporter().find('.passed > .num').should('contain', 1)
// make sure duplicate logs are not present
cy.get('.command-name-origin').find('.command-name-log').should('have.length', 2)
cy.reporter().find('.command-name-origin').find('.command-name-log').should('have.length', 2)
})
})
})
Loading
Loading