Skip to content

Commit 4726ea9

Browse files
MuazOthmantgriessermike-plummerpstakounZachJW34
authored
feat: Display Cypress Dashboard metrics in the Specs Explorer (#21250)
Co-authored-by: Muaz Othman <muazweb@gmail.com> Co-authored-by: Tim Griesser <tgriesser10@gmail.com> Co-authored-by: Mike Plummer <mikep@cypress.io> Co-authored-by: Peter Stakoun <peter@stakoun.com> Co-authored-by: Mike Plummer <mike-plummer@users.noreply.github.com> Co-authored-by: Zachary Williams <ZachJW34@gmail.com>
1 parent 24052eb commit 4726ea9

File tree

127 files changed

+5742
-483
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+5742
-483
lines changed

.vscode/cspell.json

+15-1
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,46 @@
66
"words": [
77
"Chainable",
88
"composables",
9+
"dedup",
910
"ERRORED",
1011
"execa",
12+
"Fetchable",
13+
"Fetchables",
1114
"forcedefault",
15+
"getenv",
16+
"graphcache",
17+
"headlessui",
1218
"Iconify",
19+
"intlify",
1320
"Lachlan",
21+
"loggedin",
1422
"msapplication",
1523
"NOTESTS",
1624
"OVERLIMIT",
25+
"overscan",
1726
"Pinia",
1827
"pnpm",
1928
"pseudoclass",
2029
"revparse",
2130
"Screenshotting",
31+
"semibold",
2232
"shiki",
33+
"speclist",
2334
"testid",
2435
"TIMEDOUT",
36+
"titleize",
37+
"topnav",
2538
"unconfigured",
2639
"unplugin",
2740
"unrunnable",
2841
"unstaged",
2942
"urql",
43+
"viewports",
3044
"vite",
3145
"vitejs",
3246
"vueuse",
3347
"Windi"
3448
],
3549
"ignoreWords": [],
3650
"import": []
37-
}
51+
}

.vscode/extensions.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
// Name: Volar
3030
// Description: Language server for Vue. Required for any syntax highlighting in Vue files.
31-
"vue.volar",
31+
"Vue.volar",
3232

3333
// Name: Code Spell Checker
3434
// Description: Add spell-checking help to your code.

graphql-codegen.yml

+3
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,14 @@ generates:
6767
- 'packages/frontend-shared/script/codegen-type-map.js'
6868

6969
'./packages/graphql/src/gen/cloud-source-types.gen.ts':
70+
config:
71+
useTypeImports: true
7072
schema: 'packages/graphql/schemas/cloud.graphql'
7173
plugins:
7274
- add:
7375
content: '/* eslint-disable */'
7476
- 'typescript'
77+
- 'typescript-resolvers'
7578

7679
###
7780
# Generates types for us to infer the correct keys for graphcache

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"@graphql-codegen/typed-document-node": "2.2.8",
8484
"@graphql-codegen/typescript": "2.4.2",
8585
"@graphql-codegen/typescript-operations": "2.2.3",
86+
"@graphql-codegen/typescript-resolvers": "^2.6.4",
8687
"@graphql-codegen/typescript-urql-graphcache": "2.2.3",
8788
"@graphql-tools/delegate": "8.2.1",
8889
"@graphql-tools/utils": "8.2.3",
@@ -276,4 +277,4 @@
276277
"sharp": "0.29.3",
277278
"vue-template-compiler": "2.6.12"
278279
}
279-
}
280+
}

packages/app/cypress.config.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import getenv from 'getenv'
33
import { initGitRepoForTestProject, resetGitRepoForTestProject } from './cypress/tasks/git'
44

55
const CYPRESS_INTERNAL_CLOUD_ENV = getenv('CYPRESS_INTERNAL_CLOUD_ENV', process.env.CYPRESS_INTERNAL_ENV || 'development')
6+
const CYPRESS_INTERNAL_DEV_PROJECT_ID = getenv('CYPRESS_INTERNAL_DEV_PROJECT_ID', process.env.CYPRESS_INTERNAL_DEV_PROJECT_ID || 'sehy69')
67

78
export default defineConfig({
8-
projectId: CYPRESS_INTERNAL_CLOUD_ENV === 'staging' ? 'ypt4pf' : 'sehy69',
9+
projectId: CYPRESS_INTERNAL_CLOUD_ENV === 'staging' ? 'ypt4pf' : CYPRESS_INTERNAL_DEV_PROJECT_ID,
910
retries: {
1011
runMode: 2,
1112
openMode: 0,

packages/app/cypress/e2e/cypress-in-cypress-component.cy.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,25 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
8080

8181
it('redirects to the specs list with error if a spec is not found', () => {
8282
cy.visitApp()
83-
const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
83+
const { title, intro, explainer } = defaultMessages.specPage.noSpecError
8484
const badFilePath = 'src/DoesNotExist.spec.js'
8585

8686
cy.visitApp(`/specs/runner?file=${badFilePath}`)
87-
cy.contains(noSpecErrorTitle).should('be.visible')
88-
cy.contains(noSpecErrorIntro).should('be.visible')
89-
cy.contains(noSpecErrorExplainer).should('be.visible')
87+
cy.contains(title).should('be.visible')
88+
cy.contains(intro).should('be.visible')
89+
cy.contains(explainer).should('be.visible')
9090
cy.contains(getPathForPlatform(badFilePath)).should('be.visible')
9191
cy.location()
9292
.its('href')
9393
.should('eq', 'http://localhost:4455/__/#/specs')
9494

9595
// should clear after reload
9696
cy.reload()
97-
cy.contains(noSpecErrorTitle).should('not.exist')
97+
cy.contains(title).should('not.exist')
9898
})
9999

100100
it('redirects to the specs list with error if an open spec is not found when specs list updates', () => {
101-
const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
101+
const { title, intro, explainer } = defaultMessages.specPage.noSpecError
102102

103103
const goodFilePath = 'src/TestComponent.spec.jsx'
104104

@@ -109,9 +109,9 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
109109
cy.withCtx((ctx, o) => {
110110
ctx.actions.project.setSpecs(ctx.project.specs.filter((spec) => !spec.absolute.includes(o.path)))
111111
}, { path: goodFilePath }).then(() => {
112-
cy.contains(noSpecErrorTitle).should('be.visible')
113-
cy.contains(noSpecErrorIntro).should('be.visible')
114-
cy.contains(noSpecErrorExplainer).should('be.visible')
112+
cy.contains(title).should('be.visible')
113+
cy.contains(intro).should('be.visible')
114+
cy.contains(explainer).should('be.visible')
115115
cy.contains(getPathForPlatform(goodFilePath)).should('be.visible')
116116
cy.location()
117117
.its('href')

packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
9898
})
9999

100100
it('redirects to the specs list with error if a spec is not found when navigating', () => {
101-
const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
101+
const { title, intro, explainer } = defaultMessages.specPage.noSpecError
102102
const badFilePath = 'cypress/e2e/does-not-exist.spec.js'
103103

104104
cy.visitApp(`/specs/runner?file=${badFilePath}`)
105-
cy.contains(noSpecErrorTitle).should('be.visible')
106-
cy.contains(noSpecErrorIntro).should('be.visible')
107-
cy.contains(noSpecErrorExplainer).should('be.visible')
105+
cy.contains(title).should('be.visible')
106+
cy.contains(intro).should('be.visible')
107+
cy.contains(explainer).should('be.visible')
108108
cy.contains(getPathForPlatform(badFilePath)).should('be.visible')
109109
cy.location()
110110
.its('href')
@@ -114,11 +114,11 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
114114

115115
// should clear after reload
116116
cy.reload()
117-
cy.contains(noSpecErrorTitle).should('not.exist')
117+
cy.contains(title).should('not.exist')
118118
})
119119

120120
it('redirects to the specs list with error if an open spec is not found when specs list updates', () => {
121-
const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
121+
const { title, intro, explainer } = defaultMessages.specPage.noSpecError
122122

123123
const goodFilePath = 'cypress/e2e/dom-content.spec.js'
124124

@@ -129,9 +129,9 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
129129
cy.withCtx((ctx, o) => {
130130
ctx.actions.project.setSpecs(ctx.project.specs.filter((spec) => !spec.absolute.includes(o.path)))
131131
}, { path: goodFilePath }).then(() => {
132-
cy.contains(noSpecErrorTitle).should('be.visible')
133-
cy.contains(noSpecErrorIntro).should('be.visible')
134-
cy.contains(noSpecErrorExplainer).should('be.visible')
132+
cy.contains(title).should('be.visible')
133+
cy.contains(intro).should('be.visible')
134+
cy.contains(explainer).should('be.visible')
135135
cy.contains(getPathForPlatform(goodFilePath)).should('be.visible')
136136
cy.location()
137137
.its('href')

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('Reporter Header', () => {
1313
cy.get('body').type('f')
1414

1515
cy.get('[data-selected-spec="true"]').should('contain', 'dom-content').should('have.length', '1')
16-
cy.get('[data-selected-spec="false"]').should('have.length', '18')
16+
cy.get('[data-selected-spec="false"]').should('have.length', '27')
1717
})
1818

1919
it('filters the list of specs when searching for specs', () => {
@@ -26,7 +26,7 @@ describe('Reporter Header', () => {
2626

2727
cy.get('input').clear()
2828

29-
cy.get('[data-cy="spec-file-item"]').should('have.length', '3')
29+
cy.get('[data-cy="spec-file-item"]').should('have.length', 3)
3030

3131
cy.get('input').type('asdf', { force: true })
3232

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function scaffoldTestingTypeAndVisitRunsPage (testingType: 'e2e' | 'component')
1010

1111
// make sure there are no runs found for the project ID
1212
cy.remoteGraphQLIntercept(async (obj) => {
13-
if (obj.result.data?.cloudProjectBySlug) {
13+
if (obj.result.data?.cloudProjectBySlug?.runs?.nodes) {
1414
obj.result.data.cloudProjectBySlug.runs.nodes = []
1515
}
1616

@@ -136,7 +136,7 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
136136
cy.visitApp()
137137

138138
cy.remoteGraphQLIntercept(async (obj) => {
139-
if ((obj.operationName === 'CheckCloudOrganizations_cloudViewerChange_cloudViewer' || obj.operationName === 'Runs_cloudViewer')) {
139+
if ((obj.operationName === 'CheckCloudOrganizations_cloudViewerChange_cloudViewer' || obj.operationName === 'Runs_cloudViewer' || obj.operationName === 'SpecsPageContainer_cloudViewer')) {
140140
if (obj.result.data?.cloudViewer?.organizations?.nodes) {
141141
obj.result.data.cloudViewer.organizations.nodes = []
142142
}
@@ -597,8 +597,6 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
597597
let cloudData: any
598598

599599
cy.loginUser()
600-
cy.visitApp()
601-
602600
cy.remoteGraphQLIntercept((obj) => {
603601
if (obj.operationName === 'Runs_currentProject_cloudProject_cloudProjectBySlug') {
604602
cloudData = obj.result
@@ -610,7 +608,10 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
610608
return obj.result
611609
})
612610

611+
cy.visitApp()
612+
613613
cy.findByTestId('sidebar-link-runs-page').click()
614+
614615
cy.contains('h2', 'Cannot connect to the Cypress Dashboard')
615616
cy.percySnapshot()
616617

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ describe('Sidebar Navigation', () => {
221221

222222
it('has a menu item labeled "Runs" which takes you to the Runs page', () => {
223223
cy.get('[data-cy="app-header-bar"]').findByText('Runs').should('not.exist')
224-
cy.findByText('Runs').should('be.visible').click()
224+
225+
cy.findByTestId('sidebar-link-runs-page').should('have.text', 'Runs').should('be.visible').click()
225226
cy.get('[data-cy="app-header-bar"]').findByText('Runs').should('be.visible')
226227
cy.get('.router-link-active').findByText('Runs').should('be.visible')
227228
})

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

+6-8
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,19 @@ describe('App: Spec List (E2E)', () => {
112112

113113
describe('typing the filter', function () {
114114
it('displays only matching spec', function () {
115-
cy.get('button').contains('14 Matches')
115+
cy.get('button').contains('23 Matches')
116116
cy.findByLabelText('Search Specs').type('content')
117117
cy.get('[data-cy="spec-item"]')
118118
.should('have.length', 2)
119119
.and('contain', 'dom-content.spec.js')
120120

121-
cy.get('button').contains('2 of 14 Matches')
121+
cy.get('button').contains('2 of 23 Matches')
122122

123123
cy.findByLabelText('Search Specs').clear().type('asdf')
124124
cy.get('[data-cy="spec-item"]')
125125
.should('have.length', 0)
126126

127-
cy.get('button').contains('0 of 14 Matches')
127+
cy.get('button').contains('0 of 23 Matches')
128128
})
129129

130130
it('only shows matching folders', () => {
@@ -176,7 +176,7 @@ describe('App: Spec List (E2E)', () => {
176176
.should('have.value', '')
177177

178178
cy.get('[data-cy="spec-item"]')
179-
.should('have.length', 14)
179+
.should('have.length', 23)
180180
})
181181

182182
it('clears the filter if the user presses ESC key', function () {
@@ -187,8 +187,7 @@ describe('App: Spec List (E2E)', () => {
187187
cy.findByLabelText('Search Specs')
188188
.should('have.value', '')
189189

190-
cy.get('[data-cy="spec-item"]')
191-
.should('have.length', 14)
190+
cy.get('button').contains('23 Matches')
192191
})
193192

194193
it('shows empty message if no results', function () {
@@ -203,8 +202,7 @@ describe('App: Spec List (E2E)', () => {
203202
cy.findByText('Clear Search').click()
204203
cy.focused().should('have.id', 'spec-filter')
205204

206-
cy.get('[data-cy="spec-item"]')
207-
.should('have.length', 14)
205+
cy.get('button').contains('23 Matches')
208206
})
209207

210208
//TODO: https://cypress-io.atlassian.net/browse/UNIFY-1588

0 commit comments

Comments
 (0)