Skip to content
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

feat: Debug page [IATR] #25488

Merged
merged 52 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5d44df4
feat: IATR-M0 Page Header (#24722)
amehta265 Nov 22, 2022
7141e40
Merge branch 'develop' into feature/IATR-M0
warrensplayer Dec 2, 2022
1c80741
feat: IATR-M0 Spec and Test Component (#24877)
amehta265 Dec 2, 2022
ad9d270
Merge branch 'develop' into feature/IATR-M0
warrensplayer Dec 8, 2022
c89cc92
Merge branch 'develop' into feature/IATR-M0
warrensplayer Dec 9, 2022
ee859f6
feat: IATR-M0 Debug Page (#25067)
warrensplayer Dec 13, 2022
d37581e
feat: IATR-M1.0 Debug page Header Update (#25072)
amehta265 Dec 15, 2022
05805e0
feat: debug status badge (#25152)
ZachJW34 Dec 16, 2022
3fd6a54
Merge branch 'develop' into feature/IATR-M0
warrensplayer Dec 19, 2022
68a02fc
Merge branch 'develop' into feature/IATR-M0
warrensplayer Dec 19, 2022
216d4c5
feat: run failures enhancements (#25234)
ZachJW34 Dec 22, 2022
552fe87
feat: IATR empty states (#25219) [run ci]
astone123 Dec 22, 2022
9008365
Merge branch 'develop' into feature/IATR-M0
warrensplayer Dec 23, 2022
bad5093
feat: IATR non-failure run statuses (#25286)
astone123 Dec 29, 2022
031dd8b
feat: IATR relevant run status banner (#25282)
mike-plummer Dec 30, 2022
0a3ee16
feat: IATR-M1.0 Debug Spec component update (#25263)
amehta265 Dec 31, 2022
19f76b3
feat: Add messaging for retention state exceeded (#25361)
mike-plummer Jan 5, 2023
c33ba30
feat: IATR-M0 Page Header (#24722) (#25360)
marktnoonan Jan 6, 2023
9e2bf5b
fix: only render debug artifacts when info is available (#25362)
ZachJW34 Jan 6, 2023
36a6eea
feat: Debug failed test limit (#25418) (#25434)
mike-plummer Jan 12, 2023
f9d81a8
Merge branch 'develop' into feature/IATR-M0
warrensplayer Jan 13, 2023
7d1d6e5
feat: run filtered debug tests in runner (#25265)
ZachJW34 Jan 17, 2023
1c9d06f
feat: IATR cloud data backend (#25316)
warrensplayer Jan 17, 2023
2a40aee
feat: wiring up test filters to the Debug page back end (#25492)
warrensplayer Jan 18, 2023
0322488
Merge branch 'develop' into feature/IATR-M0
warrensplayer Jan 18, 2023
aa82ddf
Quick whitespace fix
warrensplayer Jan 18, 2023
2b1fd83
Building windows and binaries
warrensplayer Jan 18, 2023
1a35da7
Addinging windows
warrensplayer Jan 18, 2023
1a31dd5
Fix for windows paths for debug filter
warrensplayer Jan 18, 2023
be5e534
fix: update query names for better logging (#25514)
warrensplayer Jan 19, 2023
771debb
chore: ui tweaks (#25555)
marktnoonan Jan 25, 2023
31e976b
feat: add help links to debug page empty states (#25586)
astone123 Jan 26, 2023
beb6d9b
Merge branch 'develop' into feature/IATR-M0
warrensplayer Jan 26, 2023
40a6ee0
fix: Debug page UI flickering (#25539)
warrensplayer Jan 27, 2023
2f8dd67
fix: fix for debug page isLoading flag (#25614)
warrensplayer Jan 27, 2023
4e2ba74
fix: debug dismiss filter and sidebar on runner (#25616)
warrensplayer Jan 30, 2023
d4fbfa7
fix: invalidate cache for debug page after run status change (#25620)
warrensplayer Jan 30, 2023
5798492
Merge branch 'develop' into feature/IATR-M0
warrensplayer Jan 30, 2023
de50f64
Adding changelog
warrensplayer Jan 30, 2023
c33d0b6
Adding more detail to the changelog
warrensplayer Jan 30, 2023
d4356d0
Changelog copy update
warrensplayer Jan 30, 2023
e752058
tests: IATR E2E tests (#25601)
lmiller1990 Jan 30, 2023
186d8c7
Merge branch 'develop' into feature/IATR-M0
warrensplayer Jan 30, 2023
a6a2baa
Final changelog copy update
warrensplayer Jan 30, 2023
dce4759
test: tweak simulated run mode and some other tests for flake (#25623)
marktnoonan Jan 30, 2023
3431008
Changelog update
warrensplayer Jan 30, 2023
3ecdd59
Updated TODO to reference issue that will address it
warrensplayer Jan 31, 2023
0b9913f
Removing unexpected blank line
warrensplayer Jan 31, 2023
7b74abc
Changelog fix
warrensplayer Jan 31, 2023
50e944b
Changelog fix
warrensplayer Jan 31, 2023
37344d7
Merge branch 'develop' into feature/IATR-M0
warrensplayer Jan 31, 2023
c09086b
Reverting CI workflows
warrensplayer Jan 31, 2023
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
4 changes: 4 additions & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

_Released 01/31/2023 (PENDING)_

**Features:**

- Easily debug failed CI test runs right from your local Cypress app with the new Debug page, powered by Cypress Cloud. For more details, see the [Debug documentation](https://on.cypress.io/debug-page). Addressed in [#25488](https://github.com/cypress-io/cypress/pull/25488).

**Bugfixes:**

- Fixed an issue where alternative Microsoft Edge Beta, Canary, and Dev binary versions were not being discovered by Cypress.
Expand Down
30 changes: 7 additions & 23 deletions packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { CY_IN_CY_SIMULATE_RUN_MODE } from '@packages/types/src/constants'

describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
it('e2e run mode spec runner header is correct', () => {
cy.scaffoldProject('cypress-in-cypress')
cy.findBrowsers()
cy.openProject('cypress-in-cypress')
cy.startAppServer()
cy.visitApp()

simulateRunModeInUI()
cy.visitApp(`/specs/runner?file=cypress/e2e/dom-content.spec.js&${CY_IN_CY_SIMULATE_RUN_MODE}`)

cy.contains('dom-content.spec').click()
cy.waitForSpecToFinish()

cy.findByTestId('aut-url').should('be.visible')
Expand All @@ -33,17 +32,14 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
// cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435
})

// TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23306
it('component testing run mode spec runner header is correct', { retries: 15 }, () => {
it('component testing run mode spec runner header is correct', () => {
cy.scaffoldProject('cypress-in-cypress')
cy.findBrowsers()
cy.openProject('cypress-in-cypress')
cy.startAppServer('component')
cy.visitApp()
simulateRunModeInUI()
cy.contains('TestComponent.spec').click()
cy.waitForSpecToFinish()
cy.visitApp(`/specs/runner?file=src/TestComponent.spec.jsx&${CY_IN_CY_SIMULATE_RUN_MODE}`)

cy.waitForSpecToFinish()
cy.findByTestId('aut-url').should('not.exist')
cy.findByTestId('playground-activator').should('not.exist')

Expand Down Expand Up @@ -81,9 +77,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
})
})

cy.visitApp()
simulateRunModeInUI()
cy.contains('dom-content.spec').click()
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')
Expand All @@ -92,13 +86,3 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => {
cy.findByTestId('sidebar').should('not.exist')
})
})

function simulateRunModeInUI () {
// this simulates run mode enough for this test
cy.window().then((win) => {
win.__CYPRESS_MODE__ = 'run'
cy.get('body').then(($el) => {
$el.find('[data-cy="sidebar"]')?.remove()
})
})
}
151 changes: 151 additions & 0 deletions packages/app/cypress/e2e/debug.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import RelevantRunsDataSource_RunsByCommitShas from '../fixtures/gql-RelevantRunsDataSource_RunsByCommitShas.json'

Cypress.on('window:before:load', (win) => {
win.__CYPRESS_GQL_NO_SOCKET__ = 'true'
})

// These mocks all the responses so we can get deterministic
// results to test the debug page.
// The JSON fixtures were generated by using a real app and capturing
// the responses.
describe('App - Debug Page', () => {
beforeEach(() => {
cy.scaffoldProject('cypress-in-cypress')
cy.openProject('cypress-in-cypress')
cy.startAppServer('component')

cy.loginUser()
cy.withCtx((ctx) => {
ctx.git?.__setGitHashesForTesting(['commit1', 'commit2'])
})

cy.remoteGraphQLIntercept((obj, _testState, options) => {
if (obj.operationName === 'RelevantRunsDataSource_RunsByCommitShas') {
obj.result.data = options.RelevantRunsDataSource_RunsByCommitShas.data
}

return obj.result
}, { RelevantRunsDataSource_RunsByCommitShas })
})

it('all tests passed', () => {
// This mocks all the responses so we can get deterministic
// results to test the debug page.
cy.intercept('POST', '/__cypress/graphql/query-Debug', {
fixture: 'debug-Passing/gql-Debug.json',
})

cy.intercept('POST', '/__cypress/graphql/query-CloudViewerAndProject_RequiredData', {
fixture: 'debug-Passing/gql-CloudViewerAndProject_RequiredData.json',
})

cy.intercept('POST', '/__cypress/graphql/query-MainAppQuery', {
fixture: 'debug-Passing/gql-MainAppQuery.json',
})

cy.intercept('POST', '/__cypress/graphql/query-SideBarNavigationContainer', {
fixture: 'debug-Passing/gql-SideBarNavigationContainer',
})

cy.intercept('POST', '/__cypress/graphql/query-HeaderBar_HeaderBarQuery', {
fixture: 'debug-Passing/gql-HeaderBar_HeaderBarQuery',
})

cy.intercept('POST', '/__cypress/graphql/query-SpecsPageContainer', {
fixture: 'debug-Passing/gql-SpecsPageContainer',
})

cy.visitApp()

cy.findByTestId('sidebar-link-debug-page').click()
cy.findByTestId('debug-container').should('be.visible')

cy.findByTestId('header-top').contains('update projectId')
cy.findByTestId('debug-header-dashboard-link')
.contains('View in Cypress Cloud')
.should('have.attr', 'href', 'https://cloud.cypress.io/projects/7p5uce/runs/2')

cy.findByTestId('debug-runNumber-PASSED').contains('#2')
cy.findByTestId('debug-commitsAhead').contains('You are 1 commit ahead')

cy.findByTestId('metadata').within(() => {
cy.get('[title="passed"]').contains('2')
cy.get('[title="failed"]').contains('0')
cy.get('[title="skipped"]').contains('0')
cy.get('[title="pending"]').contains('2')
cy.findByTestId('debug-header-branch').contains('main')
cy.findByTestId('debug-header-commitHash').contains('e9d176f')
cy.findByTestId('debug-header-author').contains('Lachlan Miller')
cy.findByTestId('debug-header-createdAt').contains('01:18')
})

cy.findByTestId('debug-passed').contains('Well Done!')
cy.findByTestId('debug-passed').contains('All your tests passed.')
cy.findByLabelText('Relevant run passed').should('be.visible').contains('0')
cy.findByTestId('run-failures').should('not.exist')
})

it('shows information about a failed spec', () => {
cy.intercept('POST', '/__cypress/graphql/query-Debug', {
fixture: 'debug-Failing/gql-Debug.json',
})

cy.intercept('POST', '/__cypress/graphql/query-CloudViewerAndProject_RequiredData', {
fixture: 'debug-Failing/gql-CloudViewerAndProject_RequiredData.json',
})

cy.intercept('POST', '/__cypress/graphql/query-MainAppQuery', {
fixture: 'debug-Failing/gql-MainAppQuery.json',
})

cy.intercept('POST', '/__cypress/graphql/query-SideBarNavigationContainer', {
fixture: 'debug-Failing/gql-SideBarNavigationContainer',
})

cy.intercept('POST', '/__cypress/graphql/query-HeaderBar_HeaderBarQuery', {
fixture: 'debug-Failing/gql-HeaderBar_HeaderBarQuery',
})

cy.intercept('POST', '/__cypress/graphql/query-SpecsPageContainer', {
fixture: 'debug-Failing/gql-SpecsPageContainer',
})

cy.visitApp()

cy.findByTestId('sidebar-link-debug-page').click()
cy.findByTestId('debug-container').should('be.visible')

cy.findByTestId('header-top').contains('chore: testing cypress')
cy.findByTestId('debug-header-dashboard-link')
.contains('View in Cypress Cloud')
.should('have.attr', 'href', 'https://cloud.cypress.io/projects/vgqrwp/runs/136')

cy.findByLabelText('Relevant run had 1 test failure').should('be.visible').contains('1')

cy.findByTestId('debug-runNumber-FAILED').contains('#136')
cy.findByTestId('debug-commitsAhead').contains('You are 1 commit ahead')

cy.findByTestId('metadata').within(() => {
cy.get('[title="passed"]').contains('1')
cy.get('[title="failed"]').contains('1')
cy.get('[title="skipped"]').contains('0')
cy.get('[title="pending"]').contains('0')
cy.findByTestId('debug-header-branch').contains('main')
cy.findByTestId('debug-header-commitHash').contains('commit1')
cy.findByTestId('debug-header-author').contains('Lachlan Miller')
cy.findByTestId('debug-header-createdAt').contains('00:19')
})

cy.findByTestId('spec-contents').within(() => {
cy.contains('src/components/InfoPanel/InfoPanel.cy.ts')
cy.findByTestId('metaData-Results-spec-duration').contains('00:04')
cy.findByTestId('metaData-Results-operating-system').contains('Linux Ubuntu')
cy.findByTestId('metaData-Results-browser').contains('Electron 106')
cy.findByTestId('metaData-Results-testing-type').contains('Component')
})

cy.findByTestId('test-row').contains('InfoPanel')
cy.findByTestId('test-row').contains('renders')
cy.findByTestId('run-failures').should('exist').should('have.attr', 'href', '#/specs/runner?file=src/components/InfoPanel/InfoPanel.cy.ts&mode=debug')
})
})
157 changes: 157 additions & 0 deletions packages/app/cypress/e2e/runner/cloud-debug-filter.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
describe('cloud debug test filtering', () => {
beforeEach(() => {
cy.scaffoldProject('cloud-debug-filter')
cy.openProject('cloud-debug-filter')
cy.startAppServer('e2e')
})

it('works with nested suites', () => {
cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js`)

cy.waitForSpecToFinish()

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/test.cy.js': ['t2'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t2')

cy.get('.debug-dismiss').contains('1 / 4 tests').click()
cy.waitForSpecToFinish({ passCount: 2, failCount: 2 })

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/test.cy.js': ['s1 t4'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t4')
})

it('wraps filter UI with large number of tests', () => {
cy.visitApp(`specs/runner?file=cypress/e2e/lots-of-tests.cy.js`)

cy.get('[data-cy="reporter-panel"]').as('reporterPanel')

cy.waitForSpecToFinish()

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/lots-of-tests.cy.js': ['test1'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/lots-of-tests.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 50 })

cy.get('@reporterPanel').then((el) => el.width(500))
cy.get('@reporterPanel').percySnapshot('wide')

cy.get('@reporterPanel').then((el) => el.width(350))
cy.get('@reporterPanel').percySnapshot('medium')

cy.get('@reporterPanel').then((el) => el.width(250))
cy.get('@reporterPanel').percySnapshot('narrow')

cy.get('@reporterPanel').then((el) => el.width(150))
cy.get('@reporterPanel').percySnapshot('skinny')
})

it('works with skips and onlys', () => {
cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js`)

cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

// .only is respected
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t1', 't3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t1')

cy.get('.debug-dismiss').click().waitForSpecToFinish()

// .only is ignored as it is not in set of filtered tests
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })

cy.get('.runnable-title').contains('t3')

cy.get('.debug-dismiss').click().waitForSpecToFinish()

// .skip is respected
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t2', 't3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1, pendingCount: 1 })
cy.get('.runnable-title').first().contains('t2')
cy.get('.runnable-title').last().contains('t3')

cy.get('.debug-dismiss').contains('2 / 4 tests').click().waitForSpecToFinish()

// suite.only is respected
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/skip-and-only.cy.js': ['t3', 's1 t4'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })
cy.get('.runnable-title').contains('t4')
})

it('works with browser filter', () => {
cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/lots-of-tests.cy.j': ['t1', 's1 t2'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/browsers.cy.js&mode=debug`)

cy.get('.runnable-title').eq(0).contains('t1 (skipped due to browser)')
cy.get('.runnable-title').eq(1).contains('s1 (skipped due to browser)')
cy.get('.runnable-title').eq(2).contains('t2')
})

it('filter is maintained across cross-domain reinitialization', () => {
cy.visitApp(`specs/runner?file=cypress/e2e/domain-change.cy.js`)

cy.get('[data-cy="reporter-panel"]').as('reporterPanel')

cy.waitForSpecToFinish()

cy.withCtx((ctx) => {
ctx.coreData.cloud.testsForRunResults = {
'cypress/e2e/lots-of-tests.cy.j': ['t2', 't3'],
}
})

cy.visitApp(`specs/runner?file=cypress/e2e/domain-change.cy.js&mode=debug`)
cy.waitForSpecToFinish({ failCount: 2 })
})
})
Loading