Skip to content

Commit 8880c90

Browse files
DerYegeruserquin
andauthored
feat(ui): implement filter for slow tests (#9705)
Co-authored-by: userquin <[email protected]>
1 parent 001e458 commit 8880c90

File tree

21 files changed

+164
-56
lines changed

21 files changed

+164
-56
lines changed

packages/ui/client/components/FilterStatus.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function toggle() {
1616

1717
<template>
1818
<label
19-
class="font-light text-sm checkbox flex items-center py-1 text-sm w-full gap-y-1 mb-1px"
19+
class="font-light text-sm checkbox w-fit flex items-center py-1 gap-y-1 mb-1px overflow-hidden"
2020
:class="disabled ? 'cursor-not-allowed op50' : 'cursor-pointer'"
2121
v-bind="$attrs"
2222
@click.prevent="toggle"
@@ -26,6 +26,7 @@ function toggle() {
2626
modelValue ? 'i-carbon:checkbox-checked-filled' : 'i-carbon:checkbox',
2727
]"
2828
text-lg
29+
flex-shrink-0
2930
aria-hidden="true"
3031
/>
3132
<input
@@ -34,13 +35,15 @@ function toggle() {
3435
:disabled="disabled"
3536
sr-only
3637
>
37-
<span flex-1 ms-2 select-none>{{ label }}</span>
38+
<span flex-1 ms-2 select-none whitespace-nowrap truncate>{{ label }}</span>
3839
</label>
3940
</template>
4041

4142
<style>
4243
.checkbox:focus-within {
4344
outline: none;
45+
border-color: initial;
46+
/* don't add outline-none here => uno will add 2px to the outline */
4447
@apply focus-base border-b-1 !mb-none;
4548
}
4649
</style>

packages/ui/client/components/ProgressBar.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const widthPending = computed(() => {
5050
absolute
5151
l-0
5252
t-0
53-
bg-red5
53+
bg-red-700 dark:bg-red-500
5454
h-3px
5555
:class="classes"
5656
:style="`width: ${widthFailed}px;`"
@@ -61,7 +61,7 @@ const widthPending = computed(() => {
6161
absolute
6262
l-0
6363
t-0
64-
bg-green5
64+
bg-green-700 dark:bg-green-500
6565
h-3px
6666
:class="classes"
6767
:style="`left: ${widthFailed}px; width: ${widthPass}px;`"
@@ -72,7 +72,7 @@ const widthPending = computed(() => {
7272
absolute
7373
l-0
7474
t-0
75-
bg-yellow5
75+
bg-yellow-700 dark:bg-yellow-500
7676
h-3px
7777
:class="classes"
7878
:style="`left: ${widthPass + widthFailed}px; width: ${widthPending}px;`"

packages/ui/client/components/StatusIcon.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ defineProps<{
1111
<template>
1212
<div
1313
v-if="state === 'pass'"
14-
text-green-500
14+
text-green-700 dark:text-green-500
1515
flex-shrink-0
1616
i-carbon:checkmark
1717
/>
1818
<div
1919
v-else-if="failedSnapshot"
2020
v-tooltip.right="'Contains failed snapshot'"
21-
text-red-500
21+
text-red-700 dark:text-red-500
2222
flex-shrink-0
2323
i-carbon:compare
2424
/>
2525
<div
2626
v-else-if="state === 'fail'"
27-
text-red-500
27+
text-red-700 dark:text-red-500
2828
flex-shrink-0
2929
i-carbon:close
3030
/>
@@ -43,5 +43,5 @@ defineProps<{
4343
i-carbon:redo
4444
rotate-90
4545
/>
46-
<div v-else text-yellow-500 flex-shrink-0 i-carbon:circle-dash animate-spin />
46+
<div v-else text-yellow-700 dark:text-yellow-500 flex-shrink-0 i-carbon:circle-dash animate-spin />
4747
</template>

packages/ui/client/components/dashboard/TestFilesEntry.vue

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,22 @@ import ErrorEntry from './ErrorEntry.vue'
3030
</div>
3131
</template>
3232

33+
<template v-if="explorerTree.summary.filesSkipped">
34+
<div i-carbon:redo rotate-90 />
35+
<div>
36+
Skip
37+
</div>
38+
<div class="number" text-purple-700 dark:text-purple-400>
39+
{{ explorerTree.summary.filesSkipped }}
40+
</div>
41+
</template>
42+
3343
<template v-if="explorerTree.summary.filesFailed">
3444
<div i-carbon-close />
3545
<div>
3646
Fail
3747
</div>
38-
<div class="number" text-red5>
48+
<div class="number" text-red-700 dark:text-red-500>
3949
{{ explorerTree.summary.filesFailed }}
4050
</div>
4151
</template>
@@ -45,7 +55,7 @@ import ErrorEntry from './ErrorEntry.vue'
4555
<div>
4656
Snapshot Fail
4757
</div>
48-
<div class="number" text-red5>
58+
<div class="number" text-red-700 dark:text-red-500>
4959
{{ explorerTree.summary.filesSnapshotFailed }}
5060
</div>
5161
</template>
@@ -55,7 +65,7 @@ import ErrorEntry from './ErrorEntry.vue'
5565
<div>
5666
Errors
5767
</div>
58-
<div class="number" text-red5>
68+
<div class="number" text-red-700 dark:text-red-500>
5969
{{ unhandledErrors.length }}
6070
</div>
6171
</template>

packages/ui/client/components/dashboard/TestsEntry.vue

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { explorerTree } from '~/composables/explorer'
33
import { filter } from '~/composables/explorer/state'
44
import DashboardEntry from './DashboardEntry.vue'
55
6-
function toggleFilter(type: 'success' | 'failed' | 'skipped' | 'total') {
6+
function toggleFilter(type: 'success' | 'failed' | 'skipped' | 'slow' | 'total') {
77
// Reset all filters first
88
filter.success = false
99
filter.failed = false
1010
filter.skipped = false
11+
filter.slow = false
1112
1213
if (type === 'total') {
1314
return
@@ -20,7 +21,7 @@ function toggleFilter(type: 'success' | 'failed' | 'skipped' | 'total') {
2021
<template>
2122
<div flex="~ wrap" justify-evenly gap-2 p="x-4" relative>
2223
<DashboardEntry
23-
text-green5
24+
text-green-700 dark:text-green-500
2425
data-testid="pass-entry"
2526
cursor-pointer
2627
hover="op80"
@@ -34,7 +35,7 @@ function toggleFilter(type: 'success' | 'failed' | 'skipped' | 'total') {
3435
</template>
3536
</DashboardEntry>
3637
<DashboardEntry
37-
:class="{ 'text-red5': explorerTree.summary.testsFailed, 'op50': !explorerTree.summary.testsFailed }"
38+
:class="{ 'text-red-700 dark:text-red-500': explorerTree.summary.testsFailed, 'op50': !explorerTree.summary.testsFailed }"
3839
data-testid="fail-entry"
3940
cursor-pointer
4041
hover="op80"
@@ -49,7 +50,7 @@ function toggleFilter(type: 'success' | 'failed' | 'skipped' | 'total') {
4950
</DashboardEntry>
5051
<DashboardEntry
5152
v-if="explorerTree.summary.testsExpectedFail"
52-
text-cyan5
53+
text-cyan-700 dark:text-cyan-500
5354
data-testid="expected-fail-entry"
5455
>
5556
<template #header>
@@ -61,7 +62,7 @@ function toggleFilter(type: 'success' | 'failed' | 'skipped' | 'total') {
6162
</DashboardEntry>
6263
<DashboardEntry
6364
v-if="explorerTree.summary.testsSkipped"
64-
op50
65+
text-purple-700 dark:text-purple-400
6566
data-testid="skipped-entry"
6667
cursor-pointer
6768
hover="op80"
@@ -100,5 +101,20 @@ function toggleFilter(type: 'success' | 'failed' | 'skipped' | 'total') {
100101
{{ explorerTree.summary.totalTests }}
101102
</template>
102103
</DashboardEntry>
104+
<DashboardEntry
105+
v-if="explorerTree.summary.testsSlow"
106+
text-yellow-700 dark:text-yellow-500
107+
data-testid="slow-entry"
108+
cursor-pointer
109+
hover="op80"
110+
@click="toggleFilter('slow')"
111+
>
112+
<template #header>
113+
Slow
114+
</template>
115+
<template #body>
116+
{{ explorerTree.summary.testsSlow }}
117+
</template>
118+
</DashboardEntry>
103119
</div>
104120
</template>

packages/ui/client/components/explorer/Explorer.vue

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script setup lang="ts">
22
import type { File, Task } from '@vitest/runner'
3-
import { useResizeObserver } from '@vueuse/core'
43
import { hideAllPoppers } from 'floating-vue'
54
import { computed, ref } from 'vue'
65
@@ -28,6 +27,14 @@ const emit = defineEmits<{
2827
}>()
2928
3029
const includeTaskLocation = computed(() => config.value.includeTaskLocation)
30+
const slowTime = computed(() => {
31+
const threshold = config.value.slowTestThreshold
32+
if (typeof threshold === 'number') {
33+
return ` (>${threshold}ms)`
34+
}
35+
36+
return ''
37+
})
3138
3239
const searchBox = ref<HTMLInputElement | undefined>()
3340
const selectProjectRef = ref<HTMLSelectElement | undefined>()
@@ -56,25 +63,10 @@ const {
5663
disableClearProjectSort,
5764
searchMatcher,
5865
} = useSearch(searchBox, selectProjectRef, sortProjectRef)
59-
60-
const filterClass = ref<string>('grid-cols-2')
61-
const filterHeaderClass = ref<string>('grid-col-span-2')
62-
63-
const testExplorerRef = ref<HTMLElement | undefined>()
64-
useResizeObserver(() => testExplorerRef.value, ([{ contentRect }]) => {
65-
if (contentRect.width < 420) {
66-
filterClass.value = 'grid-cols-2'
67-
filterHeaderClass.value = 'grid-col-span-2'
68-
}
69-
else {
70-
filterClass.value = 'grid-cols-4'
71-
filterHeaderClass.value = 'grid-col-span-4'
72-
}
73-
})
7466
</script>
7567

7668
<template>
77-
<div ref="testExplorerRef" h="full" flex="~ col">
69+
<div h="full" flex="~ col">
7870
<div>
7971
<div p="2" h-10 flex="~ gap-2" items-center bg-header border="b base">
8072
<slot name="header" :filtered-files="isFiltered || isFilteredByStatus ? filteredFiles : undefined" />
@@ -222,18 +214,17 @@ useResizeObserver(() => testExplorerRef.value, ([{ contentRect }]) => {
222214
items-center
223215
bg-header
224216
border="b-2 base"
225-
grid="~ items-center gap-x-2 rows-[auto_auto]"
226-
:class="filterClass"
217+
flex="~ wrap gap-x-4 justify-between"
227218
>
228-
<div :class="filterHeaderClass" flex="~ gap-2 items-center">
229-
<div aria-hidden="true" class="i-carbon:filter" />
219+
<div min-w-full flex="~ gap-2 items-center">
220+
<div aria-hidden="true" class="i-carbon:filter" flex-shrink-0 />
230221
<div flex-grow-1 text-sm>
231222
Filter
232223
</div>
233224
<IconButton
234225
v-tooltip.bottom="'Clear Filter'"
235226
:disabled="disableFilter"
236-
title="Clear search"
227+
title="Clear filter"
237228
icon="i-carbon:filter-remove"
238229
@click.passive="clearFilter(false)"
239230
/>
@@ -242,24 +233,25 @@ useResizeObserver(() => testExplorerRef.value, ([{ contentRect }]) => {
242233
<FilterStatus v-model="filter.success" label="Pass" />
243234
<FilterStatus v-model="filter.skipped" label="Skip" />
244235
<FilterStatus v-model="filter.onlyTests" label="Only Tests" />
236+
<FilterStatus v-model="filter.slow" :label="`Slow${slowTime}`" />
245237
</div>
246238
</div>
247239
<div class="scrolls" flex-auto py-1 @scroll.passive="hideAllPoppers">
248240
<ResultsPanel>
249241
<template v-if="initialized" #summary>
250242
<div grid="~ items-center gap-x-1 cols-[auto_min-content_auto] rows-[min-content_min-content]">
251-
<span text-red5>
243+
<span text-red-700 dark:text-red-500>
252244
FAIL ({{ testsTotal.failed }})
253245
</span>
254246
<span>/</span>
255-
<span text-yellow5>
247+
<span text-yellow-700 dark:text-yellow-500>
256248
RUNNING ({{ testsTotal.running }})
257249
</span>
258-
<span text-green5>
250+
<span text-green-700 dark:text-green-500>
259251
PASS ({{ testsTotal.success }})
260252
</span>
261253
<span>/</span>
262-
<span class="text-purple5:50">
254+
<span class="text-purple-700 dark:text-purple-400">
263255
SKIP ({{ filter.onlyTests ? testsTotal.skipped : '--' }})
264256
</span>
265257
</div>
@@ -343,6 +335,7 @@ useResizeObserver(() => testExplorerRef.value, ([{ contentRect }]) => {
343335
:project-name-color="item.projectNameColor ?? ''"
344336
:state="item.state"
345337
:duration="item.duration"
338+
:slow="item.slow === true"
346339
:opened="item.expanded"
347340
:disable-task-location="!includeTaskLocation"
348341
:class="selectedTest === item.id || (!selectedTest && activeFileId === item.id) ? 'bg-active' : ''"

packages/ui/client/components/explorer/ExplorerItem.vue

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const {
2020
indent,
2121
name,
2222
duration,
23+
slow,
2324
current,
2425
opened,
2526
expandable,
@@ -35,6 +36,7 @@ const {
3536
indent: number
3637
typecheck?: boolean
3738
duration?: number
39+
slow?: boolean
3840
state?: TaskState
3941
current: boolean
4042
type: TaskTreeNodeType
@@ -212,15 +214,20 @@ const tagsBgGradient = computed(() => {
212214
<div :class="opened ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right op20'" op20 />
213215
</div>
214216
<StatusIcon :state="state" :mode="task.mode" :failed-snapshot="failedSnapshot" w-4 />
215-
<div flex items-end gap-2 overflow-hidden>
217+
<div flex items-baseline gap-2 overflow-hidden>
216218
<div v-if="type === 'file' && typecheck" v-tooltip.bottom="'This is a typecheck test. It won\'t report results of the runtime tests'" class="i-logos:typescript-icon" flex-shrink-0 />
217219
<span text-sm truncate font-light>
218220
<span v-if="type === 'file' && projectName" class="rounded-full py-0.5 px-2 mr-1 text-xs" :style="{ backgroundColor: projectNameColor, color: projectNameTextColor }">
219221
{{ projectName }}
220222
</span>
221-
<span :text="state === 'fail' ? 'red-500' : ''" v-html="highlighted" />
223+
<span :class="state === 'fail' ? 'text-red-700 dark:text-red-500' : undefined" v-html="highlighted" />
222224
</span>
223-
<span v-if="typeof duration === 'number'" text="xs" op20 style="white-space: nowrap">
225+
<span
226+
v-if="typeof duration === 'number'"
227+
text="xs"
228+
:class="slow ? 'text-yellow-700 dark:text-yellow-500' : 'op20'"
229+
style="white-space: nowrap"
230+
>
224231
{{ duration > 0 ? duration : '< 1' }}ms
225232
</span>
226233
</div>
@@ -276,7 +283,7 @@ const tagsBgGradient = computed(() => {
276283
data-testid="btn-run-test"
277284
:title="runButtonTitle"
278285
icon="i-carbon:play-filled-alt"
279-
text-green5
286+
text-green-700 dark:text-green-500
280287
:disabled="config.api?.allowExec === false"
281288
@click.prevent.stop="onRun(task)"
282289
/>

packages/ui/client/components/views/ViewEditor.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,14 @@ function createErrorElement(e: TestError) {
158158
const div = document.createElement('div')
159159
div.className = 'op80 flex gap-x-2 items-center'
160160
const pre = document.createElement('pre')
161-
pre.className = 'c-red-600 dark:c-red-400'
161+
pre.className = 'c-red-700 dark:c-red-400'
162162
pre.textContent = `${' '.repeat(stack.column)}^ ${e.name}: ${
163163
e?.message || ''
164164
}`
165165
div.appendChild(pre)
166166
const span = document.createElement('span')
167167
span.className
168-
= 'i-carbon-launch c-red-600 dark:c-red-400 hover:cursor-pointer min-w-1em min-h-1em'
168+
= 'i-carbon-launch c-red-700 dark:c-red-400 hover:cursor-pointer min-w-1em min-h-1em'
169169
span.tabIndex = 0
170170
span.ariaLabel = 'Open in Editor'
171171
createTooltip(

packages/ui/client/components/views/ViewReportError.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function showCode(stack: ParsedStack) {
5353
- {{ relative(stack.file) }}:{{ stack.line }}:{{ stack.column }}</pre>
5454
<div
5555
v-tooltip.bottom="'Open in Editor'"
56-
class="i-carbon-launch c-red-600 dark:c-red-400 hover:cursor-pointer min-w-1em min-h-1em"
56+
class="i-carbon-launch c-red-700 dark:c-red-400 hover:cursor-pointer min-w-1em min-h-1em"
5757
tabindex="0"
5858
aria-label="Open in Editor"
5959
@click.passive="showCode(stack)"

0 commit comments

Comments
 (0)