Skip to content

Commit 5e2099e

Browse files
Merge branch 'feature/IATR-M0' into zachw/debug-artifacts-fix
2 parents 2befca5 + c33ba30 commit 5e2099e

File tree

2 files changed

+68
-27
lines changed

2 files changed

+68
-27
lines changed

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ describe('<DebugFailedTest/>', () => {
165165
cy.percySnapshot()
166166
})
167167

168-
it('tests responsvie UI', { viewportWidth: 700 }, () => {
168+
it('tests responsive UI', { viewportWidth: 700 }, () => {
169169
const testResult: TestResults = {
170170
id: '676df87874',
171171
titleParts: ['Test content', 'Test content 2', 'Test content 3', 'Test content 4', 'onMount() should be called once', 'hook() should be called twice and then'],
@@ -180,6 +180,9 @@ describe('<DebugFailedTest/>', () => {
180180

181181
assertRowContents(testResult)
182182

183+
cy.contains('...').realHover()
184+
cy.contains('[data-cy=tooltip-content]', 'Test content 2 > Test content 3 > Test content 4').should('be.visible')
185+
183186
cy.percySnapshot()
184187
})
185188

packages/app/src/debug/DebugFailedTest.vue

+64-26
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,39 @@
1010
class="isolate"
1111
/>
1212
<template
13-
v-for="titlePart, index in failedTestData.mappedTitleParts"
13+
v-for="{text, type}, index in failedTestData.mappedTitleParts"
1414
:key="`${titlePart}-${index}`"
1515
:data-cy="`titleParts-${index}`"
1616
>
1717
<IconChevronRightSmall
18-
v-if="index !== 0 && titlePart.type !== 'LAST-1'"
18+
v-if="index !== 0 && type !== 'LAST-PART-END'"
1919
:data-cy="`titleParts-${index}-chevron`"
2020
size="8"
2121
stroke-color="gray-200"
2222
fill-color="gray-200"
2323
class="shrink-0"
24-
:class="titlePart.type === 'MIDDLE' ? 'hidden lg:block' : titlePart.type === 'ELLIPSIS' ? 'lg:hidden' : ''"
24+
:class="type === 'MIDDLE' ? 'hidden lg:block' : type === 'ELLIPSIS' ? 'lg:hidden' : ''"
2525
/>
2626
<span
2727
:data-cy="`titleParts-${index}-title`"
28-
:class="titlePart.type === 'ELLIPSIS' ? 'px-2.5 shrink-0 lg:hidden' :
29-
titlePart.type === 'MIDDLE' ? 'truncate px-2.5 hidden lg:block' :
30-
titlePart.type === 'LAST-1' ? 'shrink-0 whitespace-pre' :
31-
titlePart.type === 'LAST-0' ? 'pl-2.5 truncate' : 'px-2.5 truncate'"
28+
:class="type === 'ELLIPSIS' ? 'px-2.5 shrink-0 lg:hidden' :
29+
type === 'MIDDLE' ? 'truncate px-2.5 hidden lg:block' :
30+
type === 'LAST-PART-END' ? 'shrink-0 whitespace-pre' :
31+
type === 'LAST-PART-START' ? 'pl-2.5 truncate' : 'px-2.5 truncate'"
3232
>
33-
{{ titlePart.title }}
33+
<template v-if="type === 'ELLIPSIS'">
34+
<Tooltip>
35+
<!-- button gives us free keyboard focus activation of the tooltip -->
36+
<button>{{ text }}</button>
37+
<span class="sr-only">{{ middlePartText }}</span>
38+
<template #popper>
39+
<span data-cy="tooltip-content">{{ middlePartText }}</span>
40+
</template>
41+
</Tooltip>
42+
</template>
43+
<template v-else>
44+
{{ text }}
45+
</template>
3446
</span>
3547
</template>
3648
<div
@@ -68,6 +80,7 @@ import DebugArtifactLink from './DebugArtifactLink.vue'
6880
import GroupedDebugFailedTestVue from './GroupedDebugFailedTest.vue'
6981
import { computed } from 'vue'
7082
import type { StatsMetadata_GroupsFragment } from '../generated/graphql'
83+
import Tooltip from '@packages/frontend-shared/src/components/Tooltip.vue'
7184
import { getDebugArtifacts } from './utils/debugArtifacts'
7285
import type { TestResults } from './DebugSpec.vue'
7386
import { useI18n } from '@cy/i18n'
@@ -80,61 +93,79 @@ const props = defineProps<{
8093
expandable: boolean
8194
}>()
8295
96+
type ItemType = 'SHOW_FULL' | 'MIDDLE' | 'ELLIPSIS' | 'LAST-PART-START' | 'LAST-PART-END'
97+
type MappedTitlePart = {
98+
text: string
99+
type: ItemType
100+
}
101+
83102
const failedTestData = computed(() => {
84103
const runInstance = props.failedTestsResult[0].instance
85104
const titleParts = props.failedTestsResult[0].titleParts
86105
87-
type Parts = 'FIRST' | 'MIDDLE' | 'PENULTIMATE' | 'ELLIPSIS' | 'LAST-0' | 'LAST-1'
88-
type MappedTitlePart = {
89-
title: string
90-
type: Parts
91-
}
92106
let isFirstMiddleAdded: boolean = false
93-
const mappedTitleParts: MappedTitlePart[] = titleParts.map<MappedTitlePart | MappedTitlePart[]>((ele, index, parts) => {
107+
108+
const mappedTitleParts: MappedTitlePart[] = titleParts.map<MappedTitlePart | MappedTitlePart[]>((titlePart, index, parts) => {
94109
if (index === 0) {
110+
// always use the whole first part of the title
95111
return {
96-
title: ele,
97-
type: 'FIRST',
112+
text: titlePart,
113+
type: 'SHOW_FULL',
98114
}
99115
}
100116
101117
if (index === parts.length - 1) {
118+
// split the last part into 2 pieces, so that we can truncate the first half if needed,
119+
// and still show the end of the text.
102120
return [
103121
{
104-
title: ele.slice(0, ele.length - 15),
105-
type: 'LAST-0',
122+
text: titlePart.slice(0, titlePart.length - 15),
123+
type: 'LAST-PART-START',
106124
},
107125
{
108-
title: ele.slice(ele.length - 15),
109-
type: 'LAST-1',
126+
text: titlePart.slice(titlePart.length - 15),
127+
type: 'LAST-PART-END',
110128
},
111129
]
112130
}
113131
114132
if (index === parts.length - 2 && parts.length >= 3) {
133+
// this is the second-last part of the title,
134+
// and will be the *third-to-last* item in the array.
135+
136+
// We only label this SHOW_FULL if there are enough
137+
// actual parts in the title that it is required to separate this
138+
// from "middle" items that may be hidden in smaller screens
139+
115140
return {
116-
title: ele,
117-
type: 'PENULTIMATE',
141+
text: titlePart,
142+
type: 'SHOW_FULL',
118143
}
119144
}
120145
121146
if (!isFirstMiddleAdded && parts.length > 3) {
122147
isFirstMiddleAdded = true
123148
149+
// a fake part with type ELLIPSIS is shown conditionally
150+
// at smaller screen sizes
151+
152+
// we insert it here and will flatten the result later
153+
// to undo the nesting this creates
124154
return [
125155
{
126-
title: '...',
156+
text: '...',
127157
type: 'ELLIPSIS',
128158
},
129159
{
130-
title: ele,
160+
text: titlePart,
131161
type: 'MIDDLE',
132162
},
133163
]
134164
}
135165
136-
return { title: ele, type: 'MIDDLE' }
137-
}).flat()
166+
return { text: titlePart, type: 'MIDDLE' }
167+
})
168+
.flat() // flatten the array since one of the internal items may itself be an array.
138169
139170
const debugArtifacts = getDebugArtifacts(runInstance, t)
140171
@@ -144,6 +175,13 @@ const failedTestData = computed(() => {
144175
}
145176
})
146177
178+
const middlePartText = computed(() => {
179+
return failedTestData.value.mappedTitleParts
180+
.filter((item) => item.type === 'MIDDLE')
181+
.map((item) => item.text)
182+
.join(' > ')
183+
})
184+
147185
</script>
148186
<style scoped>
149187
[data-cy=test-group]:hover .test-row-artifacts, [data-cy=test-group]:focus-within .test-row-artifacts {

0 commit comments

Comments
 (0)