Skip to content

Commit 3909ed0

Browse files
misc: Add more spec actions button and new back button for Studio mode (#32611)
* chore: Add more spec actions button * Update styles, and update studio components * Refactor Reporter components to streamline studio test handling - Removed `displayStatsAndControls` prop from `Header` and adjusted rendering logic based on `isStudioSingleTest`. - Updated `RunnableHeader` and `RunnablePopoverOptions` to conditionally render elements based on `isStudioSingleTest`. - Improved code readability and maintainability by consolidating logic related to studio tests. * Refactor Header and StudioTest components for improved styling and functionality - Updated the `Header` component to remove the `isStudioSingleTest` prop from `RunnableHeader` rendering. - Modified the `StudioTest` component to change the button styling from 'outline-dark' to 'outline-indigo' and updated the stroke color of the icon accordingly. * Update tests * Update tests * Fix styles * changelog entry * Add all tests tooltip * Update styles * maybe make semantic-commit happy --------- Co-authored-by: Jennifer Shehane <[email protected]> Co-authored-by: Jennifer Shehane <[email protected]>
1 parent ac0ad31 commit 3909ed0

27 files changed

+502
-310
lines changed

cli/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ _Released 10/07/2025 (PENDING)_
1515

1616
**Misc:**
1717

18+
- Added a dropdown menu in the Command Log that includes actions like Open in IDE and Add New Test in Studio, along with test preferences such as Auto-Scroll. Addresses [#32556](https://github.com/cypress-io/cypress/issues/32556) and [#32558](https://github.com/cypress-io/cypress/issues/32558). Addressed in [#32611](https://github.com/cypress-io/cypress/pull/32611).
19+
- Updated the Studio test editing header to include a Back button. This change ensures the Specs button remains functional for expanding or collapsing the specs panel. Addresses [#32556](https://github.com/cypress-io/cypress/issues/32556) and [#32558](https://github.com/cypress-io/cypress/issues/32558). Addressed in [#32611](https://github.com/cypress-io/cypress/pull/32611).
1820
- Fixed the Studio panel resizing when dragging. Addressed in [#32584](https://github.com/cypress-io/cypress/pull/32584).
1921

2022
## 15.3.0

packages/app/cypress/e2e/reporter_header.cy.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ describe('Reporter Header', () => {
4040
})
4141
})
4242

43-
context('Testing Preferences', () => {
43+
context('More actions button', () => {
4444
const switchSelector = '[data-cy=auto-scroll-switch]'
4545

4646
context('preferences menu', () => {
@@ -54,19 +54,23 @@ describe('Reporter Header', () => {
5454
cy.waitForSpecToFinish()
5555
})
5656

57-
it('clicking the down arrow will open a panel showing Testing Preferences', () => {
58-
cy.get('[data-cy=testing-preferences-toggle]').trigger('mouseover')
59-
cy.get('.cy-tooltip').should('have.text', 'Open Testing Preferences')
57+
it('clicking down more options will open a popover with more options', () => {
58+
cy.get('[data-cy="runnable-options-button"]').trigger('mouseover')
59+
cy.get('.cy-tooltip').should('have.text', 'Options')
6060

61-
cy.get('.testing-preferences').should('not.exist')
62-
cy.get('[data-cy=testing-preferences-toggle]').click()
63-
cy.get('.testing-preferences').should('be.visible')
64-
cy.get('[data-cy=testing-preferences-toggle]').click()
65-
cy.get('.testing-preferences').should('not.exist')
61+
cy.get('[data-cy="more-options-runnable-popover"]').should('not.exist')
62+
cy.get('[data-cy="runnable-options-button"]').click()
63+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
64+
cy.get('[data-cy="runnable-options-button"]').click()
65+
cy.get('[data-cy="more-options-runnable-popover"]').should('not.exist')
6666
})
6767

68-
it('will show a toggle beside the auto-scrolling option', () => {
69-
cy.get('[data-cy=testing-preferences-toggle]').click()
68+
it('will show multiples actions in the popover', () => {
69+
cy.get('[data-cy="runnable-options-button"]').click()
70+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
71+
cy.get('[data-cy="more-options-runnable-popover"]').should('contain', 'Open in IDE')
72+
cy.get('[data-cy="more-options-runnable-popover"]').should('contain', 'New test')
73+
cy.get('[data-cy="more-options-runnable-popover"]').should('contain', 'Auto-scrolling')
7074
cy.get(switchSelector).invoke('attr', 'aria-checked').should('eq', 'true')
7175
cy.get(switchSelector).click()
7276
cy.get(switchSelector).invoke('attr', 'aria-checked').should('eq', 'false')
@@ -95,7 +99,9 @@ describe('Reporter Header', () => {
9599
})
96100
})
97101

98-
cy.get('[data-cy=testing-preferences-toggle]').click()
102+
cy.get('[data-cy="runnable-options-button"]').click()
103+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
104+
99105
cy.get(switchSelector).invoke('attr', 'aria-checked').should('eq', 'true')
100106
})
101107
})

packages/app/cypress/e2e/runner/runner.ui.cy.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,9 @@ describe('src/cypress/runner', () => {
171171
o.sinon.stub(ctx.actions.file, 'openFile')
172172
})
173173

174-
cy.get('.open-in-ide-button').should('have.css', 'opacity', '0')
175-
cy.get('.spec-file-name').realHover()
176-
cy.get('.open-in-ide-button').first().should('have.css', 'opacity', '1').click()
174+
cy.get('[data-cy="runnable-options-button"]').click()
175+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
176+
cy.get('[data-cy="runnable-popover-open-ide"]').click()
177177

178178
cy.withCtx((ctx, o) => {
179179
expect(ctx.actions.file.openFile).to.have.been.calledWith(o.sinon.match(new RegExp(`simple-cy-assert\.runner\.cy\.js$`)), 1, 1)

packages/app/cypress/e2e/studio/helper.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ export function launchStudio ({ specName = 'spec.cy.js', createNewTestFromSuite
3030

3131
if (createNewTestFromSuite || createNewTestFromSpecHeader) {
3232
if (createNewTestFromSpecHeader) {
33-
cy.findByTestId('create-new-test-from-spec-header').click()
33+
cy.get('[data-cy="runnable-options-button"]').click()
34+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
35+
cy.get('[data-cy="runnable-popover-new-test"]').click()
3436
} else {
3537
cy.get('@runnable-wrapper').realHover().findByTestId('create-new-test-from-suite').click()
3638
}

packages/app/cypress/e2e/studio/studio.cy.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -623,10 +623,13 @@ describe('studio functionality', () => {
623623
o.sinon.stub(ctx.actions.file, 'openFile')
624624
})
625625

626-
cy.get('.open-in-ide-button').should('have.css', 'opacity', '0')
627-
cy.get('.spec-file-name').first().realHover()
628-
cy.get('.open-in-ide-button').first().should('have.css', 'opacity', '1').click()
629-
cy.get('.open-in-ide-button').first().contains('Open in IDE')
626+
cy.get('[data-cy="runnable-options-button"]').click()
627+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
628+
629+
cy.get('[data-cy="runnable-popover-open-ide"]').contains('Open in IDE')
630+
cy.get('[data-cy="runnable-popover-open-ide"]').click()
631+
632+
cy.contains('External editor preferences')
630633

631634
cy.percySnapshot()
632635
})

packages/reporter/cypress/e2e/header.cy.ts

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,28 @@ describe('header', () => {
103103
runner.emit('run:start')
104104
})
105105

106-
describe('preferences menu', () => {
107-
it('can be toggled', () => {
108-
cy.get('.testing-preferences').should('not.exist')
109-
cy.get('[data-cy=testing-preferences-toggle]').click()
110-
cy.get('.testing-preferences').should('be.visible')
111-
cy.get('[data-cy=testing-preferences-toggle]').click()
112-
cy.get('.testing-preferences').should('not.exist')
106+
describe('more options menu', () => {
107+
it('can be opened', () => {
108+
cy.get('[data-cy="runnable-options-button"]').click()
109+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
110+
111+
cy.get('[data-cy="runnable-options-button"]').click()
112+
cy.get('[data-cy="more-options-runnable-popover"]').should('not.exist')
113+
cy.get('[data-cy="runnable-options-button"]').click()
114+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
113115
})
114116

115117
it('has tooltip', () => {
116-
cy.get('[data-cy=testing-preferences-toggle]').trigger('mouseover')
117-
cy.get('.cy-tooltip').should('have.text', 'Open Testing Preferences')
118+
cy.get('[data-cy="runnable-options-button"]').trigger('mouseover')
119+
cy.get('.cy-tooltip').should('have.text', 'Options')
118120
})
119121

120122
it('shows when auto-scrolling is enabled and can disable it', () => {
121123
const switchSelector = '[data-cy=auto-scroll-switch]'
122124

123-
cy.get('[data-cy=testing-preferences-toggle]').click()
125+
cy.get('[data-cy="runnable-options-button"]').click()
126+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
127+
124128
cy.get(switchSelector).invoke('attr', 'aria-checked').should('eq', 'true')
125129
cy.get(switchSelector).click()
126130
cy.get(switchSelector).invoke('attr', 'aria-checked').should('eq', 'false')
@@ -129,7 +133,9 @@ describe('header', () => {
129133
it('can be toggled with shortcut', () => {
130134
const switchSelector = '[data-cy=auto-scroll-switch]'
131135

132-
cy.get('[data-cy=testing-preferences-toggle]').click()
136+
cy.get('[data-cy="runnable-options-button"]').click()
137+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
138+
133139
cy.get(switchSelector).invoke('attr', 'aria-checked').should('eq', 'true')
134140
cy.get('body').type('a').then(() => {
135141
cy.get(switchSelector).invoke('attr', 'aria-checked').should('eq', 'false')
@@ -138,11 +144,34 @@ describe('header', () => {
138144

139145
it('the auto-scroll toggle emits save:state event when clicked', () => {
140146
cy.spy(runner, 'emit')
141-
cy.get('[data-cy=testing-preferences-toggle]').click()
147+
148+
cy.get('[data-cy="runnable-options-button"]').click()
149+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
150+
142151
cy.get('[data-cy=auto-scroll-switch]').click()
143152
cy.wrap(runner.emit).should('be.calledWith', 'save:state')
144153
cy.percySnapshot()
145154
})
155+
156+
it('opens the open in IDE button', () => {
157+
cy.spy(runner, 'emit')
158+
159+
cy.get('[data-cy="runnable-options-button"]').click()
160+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
161+
162+
cy.get('[data-cy="runnable-popover-open-ide"]').click()
163+
cy.wrap(runner.emit).should('be.calledWith', 'open:file:unified')
164+
})
165+
166+
it('opens the new test button', () => {
167+
cy.spy(runner, 'emit')
168+
169+
cy.get('[data-cy="runnable-options-button"]').click()
170+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
171+
172+
cy.get('[data-cy="runnable-popover-new-test"]').click()
173+
cy.wrap(runner.emit).should('be.calledWith', 'studio:init:suite')
174+
})
146175
})
147176

148177
describe('stop button', () => {

packages/reporter/cypress/e2e/runnables.cy.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ describe('runnables', () => {
132132
runner.emit('reporter:start', { startTime: startTime.toISOString() })
133133
})
134134

135-
cy.get('.runnable-header span:last').should('have.text', '00:12')
135+
cy.get('.runnable-header .duration').should('have.text', '00:12')
136136
})
137137

138138
it('does not display time if no time taken', () => {
@@ -208,8 +208,9 @@ describe('runnables', () => {
208208

209209
cy.stub(runner, 'emit').callThrough()
210210

211-
cy.get(selector).as('spec-title').contains('foo.js').realHover()
212-
cy.get('.open-in-ide-button').click()
211+
cy.get('[data-cy="runnable-options-button"]').click()
212+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
213+
cy.get('[data-cy="runnable-popover-open-ide"]').click()
213214
cy.get(selector).click().then(() => {
214215
expect(runner.emit).to.be.calledWith('open:file:unified')
215216
})

packages/reporter/cypress/e2e/shortcuts.cy.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,15 @@ describe('shortcuts', function () {
118118

119119
it('toggles auto-scrolling', () => {
120120
cy.get('body').type('a')
121-
cy.get('[data-cy=testing-preferences-toggle]').click()
121+
cy.get('[data-cy="runnable-options-button"]').click()
122+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
122123
cy.get('[data-cy=auto-scroll-switch]').invoke('attr', 'aria-checked').should('eq', 'false')
123-
cy.get('[data-cy=testing-preferences-toggle]').click()
124+
cy.get('[data-cy=runnable-options-button]').click()
125+
cy.get('[data-cy="more-options-runnable-popover"]').should('not.exist')
126+
124127
cy.get('body').type('a')
125-
cy.get('[data-cy=testing-preferences-toggle]').click()
128+
cy.get('[data-cy="runnable-options-button"]').click()
129+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
126130
cy.get('[data-cy=auto-scroll-switch]').invoke('attr', 'aria-checked').should('eq', 'true')
127131
})
128132

packages/reporter/cypress/e2e/spec_title.cy.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,18 @@ describe('spec title', () => {
6060
cy.percySnapshot()
6161
})
6262

63-
it('displays Open in IDE button on spec name hover', () => {
64-
cy.get('.open-in-ide-button').should('have.css', 'opacity', '0')
65-
66-
cy.get('.spec-file-name').realHover()
67-
cy.get('.open-in-ide-button').should('have.css', 'opacity', '1')
68-
cy.get('.open-in-ide-button').contains('Open in IDE')
63+
it('displays Open in IDE button on more actions button', () => {
64+
cy.get('[data-cy="runnable-options-button"]').click()
65+
cy.get('[data-cy="more-options-runnable-popover"]').should('be.visible')
66+
cy.get('[data-cy="runnable-popover-open-ide"]').contains('Open in IDE')
6967

7068
cy.percySnapshot()
7169
})
7270

7371
itHandlesFileOpening({
7472
getRunner: () => runner,
75-
selector: '.open-in-ide-button',
73+
previousClickSelector: '[data-cy="runnable-options-button"]',
74+
selector: '[data-cy="runnable-popover-open-ide"]',
7675
file: {
7776
file: '/absolute/path/to/foo.js',
7877
line: 0,

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

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -141,25 +141,6 @@ describe('app state', () => {
141141
})
142142
})
143143

144-
context('#togglePreferencesMenu', () => {
145-
it('toggles isPreferencesMenuOpen', () => {
146-
const instance = new AppState()
147-
148-
instance.togglePreferencesMenu()
149-
expect(instance.isPreferencesMenuOpen).to.be.true
150-
instance.togglePreferencesMenu()
151-
expect(instance.isPreferencesMenuOpen).to.be.false
152-
})
153-
154-
it('sets reset value for autoScrollingEnabled', () => {
155-
const instance = new AppState()
156-
157-
instance.togglePreferencesMenu()
158-
instance.reset()
159-
expect(instance.autoScrollingEnabled).to.be.true
160-
})
161-
})
162-
163144
context('#setStudioActive', () => {
164145
it('sets studioActive', () => {
165146
const instance = new AppState()

0 commit comments

Comments
 (0)