Skip to content

feat: Reporter redesign #31914

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 53 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
0dd7d89
misc: begin work on reporter redesign
jennifer-shehane May 9, 2025
e7fed86
Merge branch 'develop' into describe-ui-update
jennifer-shehane May 12, 2025
2b41372
remove info icon on failing tests
jennifer-shehane May 13, 2025
1b5bcf6
Add new queued icon to tests
jennifer-shehane May 13, 2025
5da0904
bump react-icon
jennifer-shehane May 16, 2025
4620ef9
Merge branch 'develop' into describe-ui-update
mabela416 Jun 2, 2025
981d9e8
Merge branch 'develop' into mabel/issue-31677-reporter-redesign
mabela416 Jun 4, 2025
d786ef7
add some styles for the header
mabela416 Jun 5, 2025
89fe5c8
add some styles and icons to describe blocks
mabela416 Jun 6, 2025
8c87125
display chevron down on describe hover
mabela416 Jun 6, 2025
1424923
add css for red-400
mabela416 Jun 9, 2025
79c28a3
only display collapsible describes if there are tests in the suite
mabela416 Jun 9, 2025
195eac0
add new test on describe hover
mabela416 Jun 9, 2025
f9a18a7
add describe focus styles
mabela416 Jun 9, 2025
821a452
add describe focus styles scss
mabela416 Jun 9, 2025
295bf5b
fix add commands to test wand placement
mabela416 Jun 9, 2025
dbda5e1
update stats icon with describe and test hover and focus
mabela416 Jun 11, 2025
5ec13ed
update test status icons
mabela416 Jun 12, 2025
7ae9414
handles some of the test body styles and states
mabela416 Jun 12, 2025
2c9834d
add ellipsis to runnable title and flex shrink to icons
mabela416 Jun 12, 2025
250be10
fix command row stylings
mabela416 Jun 13, 2025
2672c3d
fix session alignment
mabela416 Jun 13, 2025
539f71a
fix collapsible indicator styles
mabela416 Jun 13, 2025
b61327d
handle attempt styling
mabela416 Jun 13, 2025
1d07123
fix failing tests
mabela416 Jun 13, 2025
6024731
add back command status borders
mabela416 Jun 13, 2025
5814706
fix suites.cy.ts tests and make some styling fixes
mabela416 Jun 16, 2025
2ba4f8a
fix styles for New test button on focused/hovered suites
mabela416 Jun 16, 2025
a36d24b
fix header test
mabela416 Jun 16, 2025
b5ebe28
attempt spacing fixes
mabela416 Jun 16, 2025
d79e24f
fix shortcuts test
mabela416 Jun 16, 2025
3ae4b79
add open in ide on header hover
mabela416 Jun 17, 2025
a906916
make some styling fixes to errors
mabela416 Jun 17, 2025
16ff0ae
make error styling changes
mabela416 Jun 17, 2025
6332f68
update control icons and styles
mabela416 Jun 18, 2025
b306514
fix dotted line for suites
mabela416 Jun 18, 2025
ae4d03a
add test dots
mabela416 Jun 18, 2025
01d02aa
fix logic for displaying test dots
mabela416 Jun 18, 2025
fc92577
use stop circle icon
mabela416 Jun 18, 2025
826ffb1
refactor runnable and suite header icon
mabela416 Jun 18, 2025
d20e896
only use test children to determine current suite state to display th…
mabela416 Jun 18, 2025
863df81
fix suites test
mabela416 Jun 18, 2025
9b02e55
fix suite and test icon alignments
mabela416 Jun 18, 2025
3395dca
clean up some comments and unused variables
mabela416 Jun 18, 2025
502ef05
Merge branch 'develop' into mabel/issue-31677-reporter-redesign
mabela416 Jun 18, 2025
88b3871
fix failing tests
mabela416 Jun 20, 2025
ef9944b
Merge remote-tracking branch 'refs/remotes/origin/mabel/issue-31677-r…
mabela416 Jun 20, 2025
e55e8ce
fix failing studio tests
mabela416 Jun 20, 2025
df3098f
fix failing tests
mabela416 Jun 20, 2025
87ea168
fix meta test
mabela416 Jun 20, 2025
ed6e520
fix suite_model test
mabela416 Jun 20, 2025
e7a4556
add more tests for suite-model
mabela416 Jun 20, 2025
9b83ab1
fix more tests
mabela416 Jun 20, 2025
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: 0 additions & 1 deletion packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('withFailure.spec').click()
cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')

cy.get('[data-cy="runnable-header"]').should('be.visible')
cy.get('body').type('f')
Expand Down
3 changes: 1 addition & 2 deletions packages/app/cypress/e2e/cypress-in-cypress.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ 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.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')
.click({ force: true })
cy.findByTestId('toggle-specs-button').click({ force: true })

// this tooltip text confirms specs list is open
cy.contains('Collapse Specs List')
Expand Down
18 changes: 14 additions & 4 deletions packages/app/cypress/e2e/runner/reporter.hooks.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ describe('hooks', {
o.sinon.stub(ctx.actions.file, 'openFile')
})

cy.contains('Open in IDE').invoke('show').click({ force: true })
cy.get('.open-in-ide-button').invoke('show').click()

cy.withCtx((ctx, o) => {
expect(ctx.actions.file.openFile).to.have.been.calledWith(o.sinon.match(new RegExp(`hooks/basic\.cy\.js$`)), o.ideLine, o.ideColumn)
}, { ideLine: 2, ideColumn: Cypress.browser.family === 'firefox' ? 5 : 2 })
expect(ctx.actions.file.openFile).to.have.been.calledWith(o.sinon.match(new RegExp(`hooks/basic\.cy\.js$`)), 1, 1)
})
})

it('does not display commands from skipped tests', () => {
Expand All @@ -84,12 +84,22 @@ describe('hooks', {
passCount: 1,
})

cy.contains('test wrapper').parents('.collapsible').first().should(($suite) => {
cy.contains('test wrapper > nested suite 1').parents('.collapsible').first().should(($suite) => {
expect($suite).not.to.contain('test 1')
expect($suite).to.contain('nested suite 1')
expect($suite).to.contain('test 2')
expect($suite).not.to.contain('nested suite 2')
expect($suite).not.to.contain('test 3')
expect($suite).not.to.contain('nested suite 3')
expect($suite).not.to.contain('test 4')
})

cy.contains('test wrapper > nested suite 3').parents('.collapsible').first().should(($suite) => {
expect($suite).not.to.contain('test 1')
expect($suite).not.to.contain('nested suite 1')
expect($suite).not.to.contain('test 2')
expect($suite).not.to.contain('nested suite 2')
expect($suite).not.to.contain('test 3')
expect($suite).to.contain('nested suite 3')
expect($suite).to.contain('test 4')
})
Expand Down
5 changes: 3 additions & 2 deletions packages/app/cypress/e2e/runner/runner.ui.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ describe('src/cypress/runner', () => {
o.sinon.stub(ctx.actions.file, 'openFile')
})

cy.contains('a', 'simple-cy-assert.runner')
.click()
cy.get('.open-in-ide-button').should('not.be.visible')
cy.get('.runnable-header-file-name').realHover()
cy.get('.open-in-ide-button').should('be.visible').click()

cy.withCtx((ctx, o) => {
expect(ctx.actions.file.openFile).to.have.been.calledWith(o.sinon.match(new RegExp(`simple-cy-assert\.runner\.cy\.js$`)), 1, 1)
Expand Down
8 changes: 4 additions & 4 deletions packages/app/cypress/e2e/runner/sessions.ui.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ describe('runner/cypress sessions.ui.spec', {
.within(() => {
cy.contains('.command-wrapper', 'Create new session')
.should('have.class', 'command-state-failed')
.find('.failed-indicator')
.find('[data-cy="failed-icon-indicator"]')
.should('exist')
})
})
Expand Down Expand Up @@ -465,7 +465,7 @@ describe('runner/cypress sessions.ui.spec', {

cy.contains('.command-wrapper', 'Validate session').as('validateSessionGroup')
.should('have.class', 'command-state-failed')
.find('.failed-indicator')
.find('[data-cy="failed-icon-indicator"]')
.should('exist')
})
})
Expand Down Expand Up @@ -528,7 +528,7 @@ describe('runner/cypress sessions.ui.spec', {

cy.contains('.command-wrapper', 'Validate session').as('validateSessionGroup')
.should('have.class', 'command-state-failed')
.find('.failed-indicator')
.find('[data-cy="failed-icon-indicator"]')
.should('exist')

const restoredMessagePostfix = 'This error occurred while validating the restored session. Because validation failed, we will try to recreate the session.'
Expand All @@ -545,7 +545,7 @@ describe('runner/cypress sessions.ui.spec', {

cy.contains('.command-wrapper', 'Recreate session')
.should('have.class', successfullyRecreatedSession ? 'command-state-passed' : 'command-state-failed')
.find('.failed-indicator')
.find('[data-cy="failed-icon-indicator"]')
.should(successfullyRecreatedSession ? 'not.exist' : 'exist', 'is-open')
})
})
Expand Down
7 changes: 4 additions & 3 deletions packages/app/cypress/e2e/runner/support/spec-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ export const shouldHaveTestResults = ({ passCount, failCount, pendingCount }) =>
failCount = failCount || '--'

cy.get('button.restart', { timeout: 30000 }).should('be.visible') // ensure tests are finished running
cy.findByLabelText('Stats', { timeout: 10000 }).within(() => {
cy.get('.passed .num', { timeout: 30000 }).should('have.text', `${passCount}`)
cy.get('.failed .num', { timeout: 30000 }).should('have.text', `${failCount}`)

cy.get('.stats', { timeout: 10000 }).within(() => {
cy.get('.passed .num', { timeout: 40000 }).should('have.text', `${passCount}`)
cy.get('.failed .num', { timeout: 40000 }).should('have.text', `${failCount}`)

if (pendingCount) {
cy.get('.pending .num', { timeout: 20000 }).should('have.text', `${pendingCount}`)
Expand Down
2 changes: 1 addition & 1 deletion packages/app/cypress/e2e/runner/support/verify-failures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const verifyFailure = (options) => {
cy.contains('.runnable-title', specTitle).closest('.runnable').as('Root')

cy.get('@Root').within(() => {
cy.contains('View stack trace').click()
cy.contains('Stack trace').click()

const messageLines = [].concat(message)

Expand Down
4 changes: 2 additions & 2 deletions packages/app/cypress/e2e/sidebar_navigation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => {

cy.contains('fixture.js').click()

cy.get('.toggle-specs-text').click()
cy.get('.toggle-specs-button').click()

cy.findByTestId('reporter-panel').invoke('outerWidth').then(($initialWidth) => {
expect($initialWidth).eq(100)
Expand Down Expand Up @@ -291,7 +291,7 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => {
it.skip('resize nav and persist the state after refresh', () => {
cy.contains('fixture.js').click()

cy.get('.toggle-specs-text').click()
cy.get('.toggle-specs-button').click()

cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.actions.localSettings, 'setPreferences').resolves()
Expand Down
5 changes: 1 addition & 4 deletions packages/app/cypress/e2e/specs_list_e2e.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ describe('App: Spec List (E2E)', () => {
cy.findAllByTestId('spec-item-link').should('have.attr', 'href')
cy.findAllByTestId('spec-item-link').contains('dom-content.spec.js').click()

cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')
cy.findByText('Your tests are loading...').should('not.be.visible')
cy.get('[data-cy="runnable-header"]').should('be.visible')
cy.get('body').type('f')
Expand All @@ -133,10 +132,8 @@ describe('App: Spec List (E2E)', () => {
cy.findAllByTestId('spec-item-link').contains('accounts_list.spec.js').click()

// ensure the tests are loaded
cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')
cy.findByText('Your tests are loading...').should('not.be.visible')

cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs')
cy.get('[data-cy="runnable-header"]').should('be.visible')
// open the inline spec list
cy.get('body').type('f')
Expand Down Expand Up @@ -369,7 +366,7 @@ describe('App: Spec List (E2E)', () => {
// A bit of a hack, but our cy-in-cy test needs to wait for the reporter to fully render before expanding the "Search specs" menu.
// Otherwise, the click happens before the event is registered, which causes the "Search Specs" menu to not expand.
cy.get('[data-cy="runnable-header"]').should('be.visible')
cy.contains('button', 'Specs').click({ force: true })
cy.findByTestId('toggle-specs-button').click({ force: true })

// wait until specs list is visible
cy.findByTestId('specs-list-container').should('be.visible')
Expand Down
10 changes: 7 additions & 3 deletions packages/app/cypress/e2e/studio/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ export function launchStudio ({ specName = 'spec.cy.js', createNewTest = false,
.closest('.runnable-wrapper').as('runnable-wrapper')
.realHover()

cy.get('@runnable-wrapper')
.findByTestId('launch-studio')
.click()
if (createNewTest) {
cy.get('@runnable-wrapper').realHover().findByTestId('create-new-test-button').click()
} else {
cy.get('@runnable-wrapper')
.findByTestId('launch-studio')
.click()
}

// Studio re-executes spec before waiting for commands - wait for the spec to finish executing.
cy.waitForSpecToFinish()
Expand Down
2 changes: 1 addition & 1 deletion packages/driver/cypress/support/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const getCommandLogWithText = (command, type?) => {
cy.$$('.runnable-active .collapsible:not(.is-open) .collapsible-header', top?.document).click()

return cy
.$$(`.runnable-active .command-${type}:contains(${command})`, top?.document)
.$$(`.test.runnable-active .command-${type}:contains(${command})`, top?.document)
.closest('.command')
}

Expand Down

This file was deleted.

14 changes: 0 additions & 14 deletions packages/reporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,6 @@ The reporter shows the running results of the tests. It includes the following:
- commands and assertions with detailed information
- any failures/errors

## Building

### For development

```bash
yarn workspace @packages/reporter build
```

### For production

```bash
yarn workspace @packages/reporter build-prod
```

## Developing

To see the reporter render, see [Developing the driver](../driver/README.md#Developing).
Expand Down
24 changes: 19 additions & 5 deletions packages/reporter/cypress/e2e/commands.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,10 @@ describe('commands', { viewportHeight: 1000 }, () => {
})

it('shows a tooltip', () => {
cy.get('.command-name-within').click('top')
cy.get('.command-name-within').within(() => {
cy.contains('within').click()
})

cy.get('.cy-tooltip').should('have.text', 'Printed output to your console')
})

Expand All @@ -911,21 +914,32 @@ describe('commands', { viewportHeight: 1000 }, () => {

it('prints to console', () => {
cy.spy(runner, 'emit')
cy.get('.command-name-within').click('top')
cy.get('.command-name-within').within(() => {
cy.contains('within').click()
})

cy.wrap(runner.emit).should('be.calledWith', 'runner:console:log', 'r3', fakeIdForTest)
})

it('shows the snapshot', () => {
cy.spy(runner, 'emit')
cy.get('.command-name-within').click('top')
cy.get('.command-name-within').within(() => {
cy.contains('within').click()
})

cy.wrap(runner.emit).should('be.calledWith', 'runner:show:snapshot', 'r3', fakeIdForTest)
})

it('unpins after clicking again, does not re-print to the console', () => {
cy.spy(runner, 'emit')
cy.get('.command-name-within').click('top')
cy.get('.command-name-within').click('top')
cy.get('.command-name-within').within(() => {
cy.contains('within').click()
})

cy.get('.command-name-within').within(() => {
cy.contains('within').click()
})

// @ts-ignore
cy.wrap(runner.emit.withArgs('runner:console:log')).should('be.calledOnce')
})
Expand Down
2 changes: 1 addition & 1 deletion packages/reporter/cypress/e2e/header.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('header', () => {
})

it('shows \'Tests\' when >= 398px wide', () => {
cy.get('.toggle-specs-wrapper span').should('be.visible')
cy.get('[data-cy=toggle-specs-button]').should('be.visible')
})
})

Expand Down
4 changes: 2 additions & 2 deletions packages/reporter/cypress/e2e/meta_&%.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
describe('special characters', () => {
it('displays file name with decoded special characters', () => {
cy.wrap(Cypress.$(window.top.document.body))
.find('.reporter .runnable-header a')
.should('have.text', 'meta_&%.cy.ts')
.find('.reporter .runnable-header')
.contains('meta_&%.cy.ts')
})
})
9 changes: 5 additions & 4 deletions packages/reporter/cypress/e2e/runnables.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ describe('runnables', () => {

it('does not display time if no time taken', () => {
start()
cy.get('.runnable-header span:first').should('have.text', 'foo.js')
cy.get('.runnable-header span:last').should('not.have.text', '--')
cy.get('.runnable-header .runnable-header-file-name').contains('foo.js')
cy.get('.runnable-header .duration').should('not.exist')
})

describe('when there are no tests', () => {
Expand Down Expand Up @@ -204,11 +204,12 @@ describe('runnables', () => {
})

it('contains name of spec and emits when clicked', () => {
const selector = '.runnable-header a'
const selector = '.runnable-header-file-name'

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

cy.get(selector).as('spec-title').contains('foo.js')
cy.get(selector).as('spec-title').contains('foo.js').realHover()
cy.get('.open-in-ide-button').click()
cy.get(selector).click().then(() => {
expect(runner.emit).to.be.calledWith('open:file:unified')
})
Expand Down
10 changes: 5 additions & 5 deletions packages/reporter/cypress/e2e/shortcuts.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,17 @@ describe('shortcuts', function () {

cy.get('body').then(() => {
expect(runner.emit).not.to.have.been.calledWith('save:state')
cy.contains('button', 'Specs').should('have.attr', 'aria-expanded', 'false')
cy.get('[data-cy=toggle-specs-button]').should('have.attr', 'aria-expanded', 'false')
})

cy.get('body').type('f').then(() => {
expect(runner.emit).to.have.been.calledWith('save:state')
cy.contains('button', 'Specs').should('have.attr', 'aria-expanded', 'true')
cy.get('[data-cy=toggle-specs-button]').should('have.attr', 'aria-expanded', 'true')
})

cy.get('body').type('f').then(() => {
expect(runner.emit).to.have.been.calledWith('save:state')
cy.contains('button', 'Specs').should('have.attr', 'aria-expanded', 'false')
cy.get('[data-cy=toggle-specs-button]').should('have.attr', 'aria-expanded', 'false')
})
})

Expand Down Expand Up @@ -140,9 +140,9 @@ describe('shortcuts', function () {
})

it('has shortcut in tooltips', () => {
cy.get('.toggle-specs-wrapper > button').trigger('mouseover')
cy.get('[data-cy=toggle-specs-button]').trigger('mouseover')
cy.get('.cy-tooltip').should('have.text', 'Expand Specs List F')
cy.get('.toggle-specs-wrapper > button').trigger('mouseout')
cy.get('[data-cy=toggle-specs-button]').trigger('mouseout')

cy.get('button.restart').trigger('mouseover')
cy.get('.cy-tooltip').should('have.text', 'Run All Tests R')
Expand Down
15 changes: 10 additions & 5 deletions packages/reporter/cypress/e2e/spec_title.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,24 @@ describe('spec title', () => {
})

it('displays name without path', () => {
cy.get('.runnable-header').find('a').should('have.text', 'foo.js')
cy.get('.runnable-header-file-name').contains('foo.js')

cy.percySnapshot()
})

it('displays tooltip on hover', () => {
cy.get('.runnable-header a').first().trigger('mouseover')
cy.get('.cy-tooltip').first().should('have.text', 'Open in IDE')
it('displays Open in IDE button on spec name hover', () => {
cy.get('.open-in-ide-button').should('have.css', 'opacity', '0')

cy.get('.runnable-header-file-name').realHover()
cy.get('.open-in-ide-button').should('have.css', 'opacity', '1')
cy.get('.open-in-ide-button').contains('Open in IDE')

cy.percySnapshot()
})

itHandlesFileOpening({
getRunner: () => runner,
selector: '.runnable-header a',
selector: '.open-in-ide-button',
file: {
file: '/absolute/path/to/foo.js',
line: 0,
Expand Down
Loading
Loading