Skip to content

Commit 2a40aee

Browse files
feat: wiring up test filters to the Debug page back end (#25492)
Closes #25487
1 parent 1c9d06f commit 2a40aee

File tree

14 files changed

+230
-73
lines changed

14 files changed

+230
-73
lines changed

packages/app/cypress/e2e/runner/cloud-debug-filter.cy.ts

+36-18
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ describe('cloud debug test filtering', () => {
1111
cy.waitForSpecToFinish()
1212

1313
cy.withCtx((ctx) => {
14-
ctx.coreData.cloud.testsForRunResults = ['t2']
14+
ctx.coreData.cloud.testsForRunResults = {
15+
'cypress/e2e/test.cy.js': ['t2'],
16+
}
1517
})
1618

17-
cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&runId=123`)
19+
cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&mode=debug`)
1820
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })
1921

2022
cy.get('.runnable-title').contains('t2')
@@ -23,10 +25,12 @@ describe('cloud debug test filtering', () => {
2325
cy.waitForSpecToFinish({ passCount: 2, failCount: 2 })
2426

2527
cy.withCtx((ctx) => {
26-
ctx.coreData.cloud.testsForRunResults = ['s1 t4']
28+
ctx.coreData.cloud.testsForRunResults = {
29+
'cypress/e2e/test.cy.js': ['s1 t4'],
30+
}
2731
})
2832

29-
cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&runId=123`)
33+
cy.visitApp(`specs/runner?file=cypress/e2e/test.cy.js&mode=debug`)
3034
cy.waitForSpecToFinish({ passCount: 0, failCount: 1 })
3135

3236
cy.get('.runnable-title').contains('t4')
@@ -40,10 +44,12 @@ describe('cloud debug test filtering', () => {
4044
cy.waitForSpecToFinish()
4145

4246
cy.withCtx((ctx) => {
43-
ctx.coreData.cloud.testsForRunResults = ['test1']
47+
ctx.coreData.cloud.testsForRunResults = {
48+
'cypress/e2e/lots-of-tests.cy.js': ['test1'],
49+
}
4450
})
4551

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

4955
cy.get('@reporterPanel').then((el) => el.width(500))
@@ -66,10 +72,12 @@ describe('cloud debug test filtering', () => {
6672

6773
// .only is respected
6874
cy.withCtx((ctx) => {
69-
ctx.coreData.cloud.testsForRunResults = ['t1', 't3']
75+
ctx.coreData.cloud.testsForRunResults = {
76+
'cypress/e2e/skip-and-only.cy.js': ['t1', 't3'],
77+
}
7078
})
7179

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

7583
cy.get('.runnable-title').contains('t1')
@@ -78,10 +86,12 @@ describe('cloud debug test filtering', () => {
7886

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

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

8797
cy.get('.runnable-title').contains('t3')
@@ -90,10 +100,12 @@ describe('cloud debug test filtering', () => {
90100

91101
// .skip is respected
92102
cy.withCtx((ctx) => {
93-
ctx.coreData.cloud.testsForRunResults = ['t2', 't3']
103+
ctx.coreData.cloud.testsForRunResults = {
104+
'cypress/e2e/skip-and-only.cy.js': ['t2', 't3'],
105+
}
94106
})
95107

96-
cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&runId=123`)
108+
cy.visitApp(`specs/runner?file=cypress/e2e/skip-and-only.cy.js&mode=debug`)
97109
cy.waitForSpecToFinish({ passCount: 0, failCount: 1, pendingCount: 1 })
98110
cy.get('.runnable-title').first().contains('t2')
99111
cy.get('.runnable-title').last().contains('t3')
@@ -102,20 +114,24 @@ describe('cloud debug test filtering', () => {
102114

103115
// suite.only is respected
104116
cy.withCtx((ctx) => {
105-
ctx.coreData.cloud.testsForRunResults = ['t3', 's1 t4']
117+
ctx.coreData.cloud.testsForRunResults = {
118+
'cypress/e2e/skip-and-only.cy.js': ['t3', 's1 t4'],
119+
}
106120
})
107121

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

113127
it('works with browser filter', () => {
114128
cy.withCtx((ctx) => {
115-
ctx.coreData.cloud.testsForRunResults = ['t1', 's1 t2']
129+
ctx.coreData.cloud.testsForRunResults = {
130+
'cypress/e2e/lots-of-tests.cy.j': ['t1', 's1 t2'],
131+
}
116132
})
117133

118-
cy.visitApp(`specs/runner?file=cypress/e2e/browsers.cy.js&runId=123`)
134+
cy.visitApp(`specs/runner?file=cypress/e2e/browsers.cy.js&mode=debug`)
119135

120136
cy.get('.runnable-title').eq(0).contains('t1 (skipped due to browser)')
121137
cy.get('.runnable-title').eq(1).contains('s1 (skipped due to browser)')
@@ -130,10 +146,12 @@ describe('cloud debug test filtering', () => {
130146
cy.waitForSpecToFinish()
131147

132148
cy.withCtx((ctx) => {
133-
ctx.coreData.cloud.testsForRunResults = ['t2', 't3']
149+
ctx.coreData.cloud.testsForRunResults = {
150+
'cypress/e2e/lots-of-tests.cy.j': ['t2', 't3'],
151+
}
134152
})
135153

136-
cy.visitApp(`specs/runner?file=cypress/e2e/domain-change.cy.js&runId=123`)
154+
cy.visitApp(`specs/runner?file=cypress/e2e/domain-change.cy.js&mode=debug`)
137155
cy.waitForSpecToFinish({ failCount: 2 })
138156
})
139157
})

packages/app/src/composables/useTestsForDebug.ts

-25
This file was deleted.

packages/app/src/debug/DebugSpec.cy.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ describe('Run Failures button', () => {
526526
))
527527

528528
cy.findByTestId('run-failures')
529-
.should('have.attr', 'href', '#/specs/runner?file=cypress/tests/auth.spec.ts')
529+
.should('have.attr', 'href', '#/specs/runner?file=cypress/tests/auth.spec.ts&mode=debug')
530530
.and('not.have.attr', 'aria-disabled')
531531
})
532532
})

packages/app/src/debug/DebugSpec.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
variant="white"
8888
class="gap-x-10px inline-flex whitespace-nowrap justify-center items-center isolate"
8989
:disabled="runAllFailuresState.disabled"
90-
:to="{ path: '/specs/runner', query: { file: posixify(specData.fullPath) } }"
90+
:to="{ path: '/specs/runner', query: { file: posixify(specData.fullPath), mode: 'debug' } }"
9191
>
9292
<template #prefix>
9393
<IconActionRefresh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { SetTestsForDebugDocument } from '../generated/graphql-test'
2+
import DebugSpecList from './DebugSpecList.vue'
3+
import type { CloudDebugSpec } from './utils/DebugMapping'
4+
5+
const specs: CloudDebugSpec[] = [{
6+
spec: {
7+
id: '123',
8+
basename: '',
9+
extension: '.ts',
10+
groupIds: [],
11+
shortPath: '',
12+
specDuration: {
13+
max: 10,
14+
min: 10,
15+
},
16+
status: 'FAILED',
17+
testsFailed: {
18+
max: 2,
19+
min: 2,
20+
},
21+
testsPassed: {
22+
max: 0,
23+
min: 0,
24+
},
25+
testsPending: {
26+
max: 0,
27+
min: 0,
28+
},
29+
path: 'path/to/test.cy.ts',
30+
},
31+
tests: {
32+
'ab123': [{
33+
id: '123',
34+
specId: '',
35+
titleParts: ['Test', 'make it work'],
36+
duration: 10,
37+
instance: {
38+
id: '123',
39+
groupId: '',
40+
hasScreenshots: false,
41+
hasStdout: false,
42+
hasVideo: false,
43+
status: 'FAILED',
44+
screenshotsUrl: '',
45+
stdoutUrl: '',
46+
videoUrl: '',
47+
totalFailed: 3,
48+
totalPassed: 0,
49+
totalPending: 0,
50+
totalRunning: 0,
51+
totalSkipped: 0,
52+
},
53+
isFlaky: false,
54+
testUrl: '',
55+
thumbprint: 'ab123',
56+
title: 'Test > make it work',
57+
}],
58+
},
59+
testingType: 'component',
60+
foundLocally: true,
61+
matchesCurrentTestingType: true,
62+
groups: { '123': {
63+
testingType: 'component',
64+
browser: {
65+
id: '123',
66+
formattedName: '',
67+
formattedNameWithVersion: '',
68+
},
69+
groupName: 'group1',
70+
id: '123',
71+
os: {
72+
id: '123',
73+
name: 'MacOS',
74+
nameWithVersion: 'MacOS 10',
75+
},
76+
} },
77+
}]
78+
79+
describe('<DebugSpecList />', () => {
80+
it('calls mutation to set tests for debug mode in runner on mount', (done) => {
81+
cy.stubMutationResolver(SetTestsForDebugDocument, (defineResult, variables) => {
82+
expect(variables.testsBySpec[0].specPath).to.eql(specs[0].spec.path)
83+
expect(variables.testsBySpec[0].tests[0]).to.eql(specs[0].tests['ab123'][0].titleParts.join(' '))
84+
done()
85+
})
86+
87+
cy.mount(() => (
88+
<DebugSpecList
89+
specs={specs}
90+
/>
91+
))
92+
})
93+
})

packages/app/src/debug/DebugSpecList.vue

+25-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
<script setup lang="ts">
2121
import { gql } from '@urql/core'
2222
import { useMutation } from '@urql/vue'
23-
import { computed } from 'vue'
24-
import { SwitchTestingTypeAndRelaunchDocument, TestingTypeEnum } from '../generated/graphql'
23+
import { computed, watchEffect } from 'vue'
24+
import { SetTestsForDebugDocument, SwitchTestingTypeAndRelaunchDocument, TestingTypeEnum } from '../generated/graphql'
2525
import DebugSpec from './DebugSpec.vue'
2626
import type { CloudDebugSpec } from './utils/DebugMapping'
2727
@@ -100,12 +100,20 @@ fragment DebugSpecListGroups on CloudRunGroup {
100100
}
101101
`
102102
103+
gql`
104+
mutation SetTestsForDebug($testsBySpec: [TestsBySpecInput!]!) {
105+
setTestsForRun (testsBySpec: $testsBySpec)
106+
}
107+
`
108+
103109
const props = defineProps<{
104110
specs: CloudDebugSpec[]
105111
}>()
106112
107113
const switchTestingTypeMutation = useMutation(SwitchTestingTypeAndRelaunchDocument)
108114
115+
const setTestsForDebug = useMutation(SetTestsForDebugDocument)
116+
109117
const specs = computed(() => {
110118
return props.specs.map((specItem) => {
111119
const fileName = specItem.spec.basename
@@ -134,4 +142,19 @@ function switchTestingType (testingType: TestingTypeEnum) {
134142
switchTestingTypeMutation.executeMutation({ testingType })
135143
}
136144
145+
watchEffect(() => {
146+
const testsNamesBySpec = props.specs.map((specItem) => {
147+
return {
148+
specPath: specItem.spec.path,
149+
tests: Object.values(specItem.tests)
150+
.flat()
151+
.map((test) => {
152+
return test.titleParts.join(' ')
153+
}),
154+
}
155+
})
156+
157+
setTestsForDebug.executeMutation({ testsBySpec: testsNamesBySpec })
158+
})
159+
137160
</script>

packages/app/src/runner/unifiedRunner.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { gql, useMutation } from '@urql/vue'
1010
import { TestsForRunDocument } from '../generated/graphql'
1111

1212
gql`
13-
mutation TestsForRun ($runId: String!) {
14-
testsForRun (runId: $runId)
13+
mutation TestsForRun ($spec: String!) {
14+
testsForRun (spec: $spec)
1515
}
1616
`
1717

@@ -61,8 +61,8 @@ export function useUnifiedRunner () {
6161
return specStore.setActiveSpec(null)
6262
}
6363

64-
if (route.query.runId) {
65-
const res = await testsForRunMutation.executeMutation({ runId: route.query.runId as string })
64+
if (route.query.mode && route.query.mode === 'debug') {
65+
const res = await testsForRunMutation.executeMutation({ spec: activeSpecInSpecsList.relative })
6666

6767
specStore.setTestFilter(res.data?.testsForRun?.length ? res.data.testsForRun : undefined)
6868
} else {

packages/app/src/runner/useEventManager.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function useEventManager () {
6464
eventManager.on('testFilter:cloudDebug:dismiss', () => {
6565
const currentRoute = router.currentRoute.value
6666

67-
const { runId, ...query } = currentRoute.query
67+
const { mode, ...query } = currentRoute.query
6868

6969
// Delete runId from query which will remove the test filter and trigger a rerun
7070
router.replace({ ...currentRoute, query })

packages/data-context/src/data/coreDataShape.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ interface Diagnostics {
114114
}
115115

116116
interface CloudDataShape {
117-
testsForRunResults?: string[]
117+
testsForRunResults?: Record<string, string[]>
118118
}
119119

120120
export interface CoreDataShape {
@@ -224,9 +224,8 @@ export function makeCoreData (modeOptions: Partial<AllModeOptions> = {}): CoreDa
224224
packageManager: 'npm',
225225
forceReconfigureProject: null,
226226
versionData: null,
227-
// TODO: Replace stubbed data with real data from cloud
228227
cloud: {
229-
testsForRunResults: ['t1', 't2', 's1 t3', 's1 t4'],
228+
testsForRunResults: {},
230229
},
231230
}
232231
}

0 commit comments

Comments
 (0)