Skip to content

Commit 9e2bf5b

Browse files
fix: only render debug artifacts when info is available (#25362)
Co-authored-by: Stokes Player <stokes@cypress.io>
1 parent c33ba30 commit 9e2bf5b

16 files changed

+144
-100
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import DebugArtifactLink from './DebugArtifactLink.vue'
2+
import type { ArtifactType } from './utils/debugArtifacts'
23

34
describe('<DebugArtifacts />', () => {
4-
const artifactMapping: {icon: string, text: string, url: string}[] = [
5+
const artifactMapping: {icon: ArtifactType, text: string, url: string}[] = [
56
{ icon: 'TERMINAL_LOG', text: 'View Log', url: 'www.cypress.io' },
67
{ icon: 'IMAGE_SCREENSHOT', text: 'View Screenshot', url: 'cloud.cypress.io' },
78
{ icon: 'PLAY', text: 'View Video', url: 'www.cypress.io' },

packages/app/src/debug/DebugArtifactLink.vue

+3-4
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,14 @@
3232
import { IconTechnologyTerminalLog, IconTechnologyImageScreenshot, IconActionPlaySmall } from '@cypress-design/vue-icon'
3333
import Tooltip from '@packages/frontend-shared/src/components/Tooltip.vue'
3434
import ExternalLink from '@cy/gql-components/ExternalLink.vue'
35+
import type { ArtifactType } from './utils/debugArtifacts'
3536
3637
const props = defineProps<{
37-
icon: string
38+
icon: ArtifactType
3839
popperText: string
39-
url: string | null | undefined
40+
url: string
4041
}>()
4142
42-
type ArtifactType = 'TERMINAL_LOG' | 'IMAGE_SCREENSHOT' | 'PLAY'
43-
4443
const ICON_MAP: Record<ArtifactType, any> = {
4544
'TERMINAL_LOG': IconTechnologyTerminalLog,
4645
'IMAGE_SCREENSHOT': IconTechnologyImageScreenshot,

packages/app/src/debug/DebugContainer.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
<script setup lang="ts">
5656
import { gql } from '@urql/vue'
57-
import { computed } from '@vue/reactivity'
57+
import { computed } from 'vue'
5858
import type { CloudRunStatus, DebugSpecsFragment, TestingTypeEnum } from '../generated/graphql'
5959
import { useLoginConnectStore } from '@packages/frontend-shared/src/store/login-connect-store'
6060
import DebugPageHeader from './DebugPageHeader.vue'

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

+59-41
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,26 @@ const group2 = {
3131
id: '456',
3232
}
3333

34+
const instance1: TestResults['instance'] = {
35+
id: '123',
36+
groupId: '123',
37+
status: 'FAILED',
38+
hasScreenshots: true,
39+
screenshotsUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/screenshots',
40+
hasStdout: true,
41+
stdoutUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/stdout',
42+
hasVideo: true,
43+
videoUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/video',
44+
}
45+
46+
const instance2: TestResults['instance'] = {
47+
...instance1,
48+
id: '456',
49+
groupId: '456',
50+
}
51+
3452
/**
35-
* This helper testing function mimicks mappedTitleParts in DebugFailedTest.
53+
* This helper testing function mimics mappedTitleParts in DebugFailedTest.
3654
* It creates an ordered array of titleParts and chevron icons and then asserts
3755
* the order in which they are rendered using the testAttr and text values.
3856
*/
@@ -84,14 +102,7 @@ describe('<DebugFailedTest/>', () => {
84102
const testResult: TestResults = {
85103
id: '676df87878',
86104
titleParts: ['Login', 'Should redirect unauthenticated user to signin page'],
87-
instance: {
88-
id: '123',
89-
groupId: '123',
90-
status: 'FAILED',
91-
hasScreenshots: false,
92-
hasStdout: false,
93-
hasVideo: false,
94-
},
105+
instance: instance1,
95106
}
96107

97108
cy.mount(() => (
@@ -114,14 +125,7 @@ describe('<DebugFailedTest/>', () => {
114125
const multipleTitleParts: TestResults = {
115126
id: '676df87878',
116127
titleParts: ['Login', 'Describe', 'it', 'context', 'Should redirect unauthenticated user to signin page'],
117-
instance: {
118-
id: '456',
119-
groupId: '456',
120-
status: 'FAILED',
121-
hasScreenshots: false,
122-
hasStdout: false,
123-
hasVideo: false,
124-
},
128+
instance: instance1,
125129
}
126130

127131
cy.mount(() => (
@@ -138,26 +142,12 @@ describe('<DebugFailedTest/>', () => {
138142
{
139143
id: '676df87878',
140144
titleParts: ['Login', 'Describe', 'it', 'context', 'Should redirect unauthenticated user to signin page'],
141-
instance: {
142-
id: '456',
143-
groupId: '456',
144-
status: 'FAILED',
145-
hasScreenshots: false,
146-
hasStdout: false,
147-
hasVideo: false,
148-
},
145+
instance: instance1,
149146
},
150147
{
151148
id: '676df87878',
152149
titleParts: ['Login', 'Should redirect unauthenticated user to signin page'],
153-
instance: {
154-
id: '123',
155-
groupId: '123',
156-
status: 'FAILED',
157-
hasScreenshots: false,
158-
hasStdout: false,
159-
hasVideo: false,
160-
},
150+
instance: instance2,
161151
},
162152
]
163153

@@ -179,14 +169,7 @@ describe('<DebugFailedTest/>', () => {
179169
const testResult: TestResults = {
180170
id: '676df87874',
181171
titleParts: ['Test content', 'Test content 2', 'Test content 3', 'Test content 4', 'onMount() should be called once', 'hook() should be called twice and then'],
182-
instance: {
183-
id: '123',
184-
groupId: '123',
185-
status: 'FAILED',
186-
hasScreenshots: false,
187-
hasStdout: false,
188-
hasVideo: false,
189-
},
172+
instance: instance1,
190173
}
191174

192175
cy.mount(() => (
@@ -202,4 +185,39 @@ describe('<DebugFailedTest/>', () => {
202185

203186
cy.percySnapshot()
204187
})
188+
189+
it('conditionally renders artifacts', () => {
190+
const render = (testResult: TestResults) => cy.mount(() =>
191+
(<div data-cy="test-group">
192+
<DebugFailedTest failedTestsResult={[testResult]} groups={[group1]} expandable={false}/>
193+
</div>))
194+
195+
const testResult: TestResults = {
196+
id: '676df87874',
197+
titleParts: ['Test content', 'Test content 2', 'Test content 3', 'Test content 4', 'onMount() should be called once', 'hook() should be called twice and then'],
198+
instance: instance1,
199+
}
200+
201+
const artifactFreeInstance: TestResults['instance'] = {
202+
...instance1,
203+
hasStdout: false,
204+
hasScreenshots: false,
205+
hasVideo: false,
206+
}
207+
208+
render({ ...testResult, instance: artifactFreeInstance })
209+
cy.findByTestId('debug-artifacts').children().should('have.length', 0)
210+
211+
render({ ...testResult, instance: { ...artifactFreeInstance, hasStdout: true } })
212+
cy.findByTestId('debug-artifacts').children().should('have.length', 1)
213+
cy.findByTestId('TERMINAL_LOG-button').should('exist')
214+
215+
render({ ...testResult, instance: { ...artifactFreeInstance, hasScreenshots: true } })
216+
cy.findByTestId('debug-artifacts').children().should('have.length', 1)
217+
cy.findByTestId('IMAGE_SCREENSHOT-button').should('exist')
218+
219+
render({ ...testResult, instance: { ...artifactFreeInstance, hasVideo: true } })
220+
cy.findByTestId('debug-artifacts').children().should('have.length', 1)
221+
cy.findByTestId('PLAY-button').should('exist')
222+
})
205223
})

packages/app/src/debug/DebugFailedTest.vue

+8-6
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,13 @@ import { SolidStatusIcon } from '@cypress-design/vue-statusicon'
7979
import DebugArtifactLink from './DebugArtifactLink.vue'
8080
import GroupedDebugFailedTestVue from './GroupedDebugFailedTest.vue'
8181
import { computed } from 'vue'
82-
import type { TestResults } from './DebugSpec.vue'
8382
import type { StatsMetadata_GroupsFragment } from '../generated/graphql'
8483
import Tooltip from '@packages/frontend-shared/src/components/Tooltip.vue'
84+
import { getDebugArtifacts } from './utils/debugArtifacts'
85+
import type { TestResults } from './DebugSpec.vue'
86+
import { useI18n } from '@cy/i18n'
87+
88+
const { t } = useI18n()
8589
8690
const props = defineProps<{
8791
failedTestsResult: TestResults[]
@@ -163,12 +167,10 @@ const failedTestData = computed(() => {
163167
})
164168
.flat() // flatten the array since one of the internal items may itself be an array.
165169
170+
const debugArtifacts = getDebugArtifacts(runInstance, t)
171+
166172
return {
167-
debugArtifacts: [
168-
{ icon: 'TERMINAL_LOG', text: 'View Log', url: runInstance?.stdoutUrl! },
169-
{ icon: 'IMAGE_SCREENSHOT', text: 'View Screenshot', url: runInstance?.screenshotsUrl! },
170-
{ icon: 'PLAY', text: 'View Video', url: runInstance?.videoUrl! },
171-
],
173+
debugArtifacts,
172174
mappedTitleParts,
173175
}
174176
})

packages/app/src/debug/DebugOverLimit.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import type { DebugReasonsRunIsHiddenFragment, OverLimitActionTypeEnum } from '.
2727
import { getUtmSource } from '@packages/frontend-shared/src/utils/getUtmSource'
2828
import { useI18n } from '@cy/i18n'
2929
import { getUrlWithParams } from '@packages/frontend-shared/src/utils/getUrlWithParams'
30-
import { computed } from '@vue/reactivity'
30+
import { computed } from 'vue'
3131
3232
export type CloudRunHidingReason = DebugReasonsRunIsHiddenFragment['reasonsRunIsHidden'][number]
3333

packages/app/src/debug/DebugPageDetails.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
</div>
3434
</template>
3535
<script lang="ts" setup>
36-
import { computed } from '@vue/reactivity'
36+
import { computed } from 'vue'
3737
import { gql } from '@urql/vue'
3838
import type { CloudRunStatus, OverLimitActionTypeEnum, DebugSpecListSpecFragment, DebugPageDetails_CloudCiBuildInfoFragment } from '../generated/graphql'
3939
import DebugCancelledAlert from './DebugCancelledAlert.vue'

packages/app/src/debug/DebugPendingRunCounts.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
<script setup lang="ts">
1111
import { gql } from '@urql/core'
12-
import { computed } from '@vue/reactivity'
12+
import { computed } from 'vue'
1313
import { useI18n } from 'vue-i18n'
1414
import type { CloudSpecStatus } from '../generated/graphql'
1515

packages/app/src/debug/DebugRunNumber.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</template>
1515

1616
<script setup lang="ts">
17-
import { computed } from '@vue/reactivity'
17+
import { computed } from 'vue'
1818
import type { CloudRunStatus } from '../generated/graphql'
1919
import { SolidStatusIcon, StatusType } from '@cypress-design/vue-statusicon'
2020

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import type { TestResults, Spec } from './DebugSpec.vue'
2-
import DebugSpec from './DebugSpec.vue'
1+
import DebugSpec, { Spec, TestResults } from './DebugSpec.vue'
32
import { defaultMessages } from '@cy/i18n'
43

54
const resultCounts = (min: number, max: number) => {

packages/app/src/debug/DebugSpec.vue

+15-15
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
</div>
4343
<ul
4444
data-cy="spec-header-metadata"
45-
class="flex flex-wrap items-center gap-x-3 text-gray-700 whitespace-nowrap children:flex children:items-center font-normal text-sm"
45+
class="flex flex-wrap font-normal text-sm text-gray-700 gap-x-3 items-center whitespace-nowrap children:flex children:items-center"
4646
>
4747
<li
4848
:data-cy="'debugHeader-results'"
@@ -141,6 +141,20 @@
141141
</template>
142142
<script lang="ts" setup>
143143
144+
import { computed, unref } from 'vue'
145+
import { IconActionRefresh, IconDocumentText } from '@cypress-design/vue-icon'
146+
import type { SpecDataAggregate, CloudRunInstance } from '@packages/data-context/src/gen/graphcache-config.gen'
147+
import DebugFailedTest from './DebugFailedTest.vue'
148+
import StatsMetaData from './StatsMetadata.vue'
149+
import ResultCounts from '@packages/frontend-shared/src/components/ResultCounts.vue'
150+
import Button from '@packages/frontend-shared/src/components/Button.vue'
151+
import Tooltip from '@packages/frontend-shared/src/components/Tooltip.vue'
152+
import SpecNameDisplay from '../specs/SpecNameDisplay.vue'
153+
import { useI18n } from '@cy/i18n'
154+
import { useDurationFormat } from '../composables/useDurationFormat'
155+
import { posixify } from '../paths'
156+
import type { StatsMetadata_GroupsFragment, TestingTypeEnum } from '../generated/graphql'
157+
144158
export interface Spec {
145159
id: string
146160
path: string
@@ -159,20 +173,6 @@ export interface TestResults {
159173
readonly instance: CloudRunInstance | null
160174
}
161175
162-
import { computed, unref } from 'vue'
163-
import { IconActionRefresh, IconDocumentText } from '@cypress-design/vue-icon'
164-
import type { SpecDataAggregate, CloudRunInstance } from '@packages/data-context/src/gen/graphcache-config.gen'
165-
import DebugFailedTest from './DebugFailedTest.vue'
166-
import StatsMetaData from './StatsMetadata.vue'
167-
import ResultCounts from '@packages/frontend-shared/src/components/ResultCounts.vue'
168-
import Button from '@packages/frontend-shared/src/components/Button.vue'
169-
import Tooltip from '@packages/frontend-shared/src/components/Tooltip.vue'
170-
import SpecNameDisplay from '../specs/SpecNameDisplay.vue'
171-
import { useI18n } from '@cy/i18n'
172-
import { useDurationFormat } from '../composables/useDurationFormat'
173-
import { posixify } from '../paths'
174-
import type { StatsMetadata_GroupsFragment, TestingTypeEnum } from '../generated/graphql'
175-
176176
const { t } = useI18n()
177177
178178
const props = defineProps<{

packages/app/src/debug/DebugSpecList.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<script setup lang="ts">
2121
import { gql } from '@urql/core'
2222
import { useMutation } from '@urql/vue'
23-
import { computed } from '@vue/reactivity'
23+
import { computed } from 'vue'
2424
import { SwitchTestingTypeAndRelaunchDocument, TestingTypeEnum } from '../generated/graphql'
2525
import DebugSpec from './DebugSpec.vue'
2626
import type { CloudDebugSpec } from './utils/DebugMapping'

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

+14-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import GroupedDebugFailedTest from './GroupedDebugFailedTest.vue'
21
import type { TestResults } from './DebugSpec.vue'
2+
import GroupedDebugFailedTest from './GroupedDebugFailedTest.vue'
33

44
describe('<GroupedDebugFailedTest/>', () => {
55
const testResult: TestResults[] = [
@@ -8,14 +8,14 @@ describe('<GroupedDebugFailedTest/>', () => {
88
titleParts: ['Login', 'Should redirect unauthenticated user to signin page'],
99
instance: {
1010
id: '123',
11-
status: 'FAILED',
1211
groupId: '123',
12+
status: 'FAILED',
1313
hasScreenshots: true,
14-
screenshotsUrl: 'www.cypress.io',
14+
screenshotsUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/screenshots',
1515
hasStdout: true,
16-
stdoutUrl: 'www.cypress.io',
16+
stdoutUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/stdout',
1717
hasVideo: true,
18-
videoUrl: 'www.cypress.io',
18+
videoUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/video',
1919
},
2020
},
2121
{
@@ -26,11 +26,11 @@ describe('<GroupedDebugFailedTest/>', () => {
2626
status: 'FAILED',
2727
groupId: '456',
2828
hasScreenshots: true,
29-
screenshotsUrl: 'cloud.cypress.io',
29+
screenshotsUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/screenshots',
3030
hasStdout: true,
31-
stdoutUrl: 'cloud.cypress.io',
31+
stdoutUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/stdout',
3232
hasVideo: true,
33-
videoUrl: 'cloud.cypress.io',
33+
videoUrl: 'https://cloud.cypress.io/projects/123/runs/456/overview/789/video',
3434
},
3535
},
3636
]
@@ -73,15 +73,12 @@ describe('<GroupedDebugFailedTest/>', () => {
7373
</div>
7474
))
7575

76-
cy.findAllByTestId(`grouped-row`).should('have.length', 2)
77-
.each((el) => {
78-
cy.wrap(el).findByTestId('debug-artifacts').should('not.be.visible')
79-
cy.wrap(el).realHover().then(() => {
80-
cy.wrap(el).findByTestId('debug-artifacts').should('be.visible').children().should('have.length', 3)
81-
})
82-
83-
cy.wrap(el).findByTestId('stats-metadata').children().should('have.length', 3)
84-
})
76+
cy.findAllByTestId(`grouped-row`).should('have.length', 2).each((el) => cy.wrap(el).within(() => {
77+
cy.findByTestId('debug-artifacts').should('not.be.visible')
78+
cy.wrap(el).realHover()
79+
cy.findByTestId('debug-artifacts').should('be.visible').children().should('have.length', 3)
80+
cy.findByTestId('stats-metadata').children().should('have.length', 3)
81+
}))
8582

8683
cy.percySnapshot()
8784
})

0 commit comments

Comments
 (0)