From 0dfa175a9724a1d96df63507ecf10b70d1014e5d Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 8 Apr 2026 18:19:04 +0900 Subject: [PATCH 001/118] wip: builtin trace system --- packages/browser/src/client/tester/context.ts | 25 +++-- .../src/client/tester/expect-element.ts | 7 ++ .../src/client/tester/locators/index.ts | 21 ++-- packages/browser/src/client/tester/runner.ts | 16 ++++ .../browser/src/client/tester/trace-state.ts | 33 +++++++ packages/runner/src/types/tasks.ts | 27 +++++- .../client/components/artifacts/Artifacts.vue | 12 +++ .../ui/client/components/trace/TraceList.vue | 95 +++++++++++++++++++ .../ui/client/components/trace/TraceView.vue | 35 +++++++ 9 files changed, 258 insertions(+), 13 deletions(-) create mode 100644 packages/browser/src/client/tester/trace-state.ts create mode 100644 packages/ui/client/components/trace/TraceList.vue create mode 100644 packages/ui/client/components/trace/TraceView.vue diff --git a/packages/browser/src/client/tester/context.ts b/packages/browser/src/client/tester/context.ts index 5d230a8803d2..598c27dc2ad6 100644 --- a/packages/browser/src/client/tester/context.ts +++ b/packages/browser/src/client/tester/context.ts @@ -19,6 +19,7 @@ import type { Locator as LocatorAPI } from './locators/index' import { vi } from 'vitest' import { __INTERNAL, stringify } from 'vitest/internal/browser' import { ensureAwaited, getBrowserState, getWorkerState } from '../utils' +import { recordBrowserTraceEntry } from './trace-state' import { convertToSelector, isLocator, processTimeoutOptions, resolveUserEventWheelOptions } from './tester-utils' // this file should not import anything directly, only types and utils @@ -365,6 +366,11 @@ export const page: BrowserPage = { if (typeof bodyOrOptions === 'function') { return ensureAwaited(async (error) => { if (hasActiveTrace) { + recordBrowserTraceEntry({ + kind: 'group', + name, + stack: options?.stack ?? error?.stack, + }) await triggerCommand( '__vitest_groupTraceStart', [{ @@ -389,14 +395,21 @@ export const page: BrowserPage = { return Promise.resolve() } - return ensureAwaited(error => triggerCommand( - '__vitest_markTrace', - [{ + return ensureAwaited((error) => { + recordBrowserTraceEntry({ + kind: 'mark', name, stack: bodyOrOptions?.stack ?? error?.stack, - }], - error, - )) + }) + return triggerCommand( + '__vitest_markTrace', + [{ + name, + stack: bodyOrOptions?.stack ?? error?.stack, + }], + error, + ) + }) }, getByRole() { throw new Error(`Method "getByRole" is not supported by the "${provider}" provider.`) diff --git a/packages/browser/src/client/tester/expect-element.ts b/packages/browser/src/client/tester/expect-element.ts index 0847ed0c233e..daa5c2059435 100644 --- a/packages/browser/src/client/tester/expect-element.ts +++ b/packages/browser/src/client/tester/expect-element.ts @@ -4,6 +4,7 @@ import { chai, expect } from 'vitest' import { getType } from 'vitest/internal/browser' import { getBrowserState, getWorkerState } from '../utils' import { matchers } from './expect' +import { recordBrowserTraceEntry } from './trace-state' import { processTimeoutOptions } from './tester-utils' const kLocator = Symbol.for('$$vitest:locator') @@ -67,6 +68,12 @@ function element(elementOrL const selector = !elementOrLocator || elementOrLocator instanceof Element ? undefined : elementOrLocator.selector + recordBrowserTraceEntry({ + kind: 'mark', + name: traceName, + selector, + stack: sourceError.stack, + }) await getBrowserState().commands.triggerCommand( '__vitest_markTrace', [{ diff --git a/packages/browser/src/client/tester/locators/index.ts b/packages/browser/src/client/tester/locators/index.ts index da5101efd953..8028793a5482 100644 --- a/packages/browser/src/client/tester/locators/index.ts +++ b/packages/browser/src/client/tester/locators/index.ts @@ -28,6 +28,7 @@ import { import { page, server, utils } from 'vitest/browser' import { __INTERNAL, getSafeTimers } from 'vitest/internal/browser' import { ensureAwaited, getBrowserState, getWorkerState } from '../../utils' +import { recordBrowserTraceEntry } from '../trace-state' import { escapeForTextSelector, isLocator, processTimeoutOptions, resolveUserEventWheelOptions } from '../tester-utils' export { ensureAwaited } from '../../utils' @@ -207,15 +208,23 @@ export abstract class Locator { if (!currentTest || !getBrowserState().activeTraceTaskIds.has(currentTest.id)) { return Promise.resolve() } - return ensureAwaited(error => getBrowserState().commands.triggerCommand( - '__vitest_markTrace', - [{ + return ensureAwaited((error) => { + recordBrowserTraceEntry({ + kind: 'mark', name, selector: this.selector, stack: options?.stack ?? error?.stack, - }], - error, - )) + }) + return getBrowserState().commands.triggerCommand( + '__vitest_markTrace', + [{ + name, + selector: this.selector, + stack: options?.stack ?? error?.stack, + }], + error, + ) + }) } protected abstract locator(selector: string): Locator diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index 48dfe4dfe593..4d10e379aa3d 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -1,4 +1,5 @@ import type { + BrowserTraceArtifact, CancelReason, File, Suite, @@ -31,6 +32,7 @@ import { createStackString, parseStacktrace } from '../../../../utils/src/source import { getBrowserState, getWorkerState, moduleRunner } from '../utils' import { rpc } from './rpc' import { VitestBrowserSnapshotEnvironment } from './snapshot' +import { consumeBrowserTraceEntries, recordBrowserTraceEntry } from './trace-state' interface BrowserRunnerOptions { config: SerializedConfig @@ -109,6 +111,12 @@ export function createBrowserRunner( if (!getBrowserState().activeTraceTaskIds.has(test.id)) { return } + // TODO: silly. not the entry itself, but retry should just isolate traces. + recordBrowserTraceEntry({ + kind: 'retry', + name: `onAfterRetryTask [${test.result?.state}]`, + stack: test.result?.errors?.[0].stack, + }, test.id) await this.commands.triggerCommand('__vitest_markTrace', [{ name: `onAfterRetryTask [${test.result?.state}]`, stack: test.result?.errors?.[0].stack, @@ -129,6 +137,7 @@ export function createBrowserRunner( await super.onAfterRunTask?.(task) const trace = this.config.browser.trace const traces = this.traces.get(task.id) || [] + const traces2 = consumeBrowserTraceEntries(task.id) if (traces.length) { if (trace === 'retain-on-failure' && task.result?.state === 'pass') { await this.commands.triggerCommand( @@ -143,6 +152,13 @@ export function createBrowserRunner( ) } } + if (traces2.length) { + await recordArtifact(task, { + type: 'internal:browserTrace', + kind: 'trace2', + entries: traces2, + } satisfies BrowserTraceArtifact) + } if (this.config.bail && task.result?.state === 'fail') { const previousFailures = await rpc().getCountOfFailedTests() diff --git a/packages/browser/src/client/tester/trace-state.ts b/packages/browser/src/client/tester/trace-state.ts new file mode 100644 index 000000000000..76da69df7ad8 --- /dev/null +++ b/packages/browser/src/client/tester/trace-state.ts @@ -0,0 +1,33 @@ +import { getWorkerState } from '../utils' + +export interface BrowserTraceEntry { + // TODO: silly + kind: 'mark' | 'group' | 'retry' + name: string + timestamp: number + stack?: string + selector?: string +} + +const browserTraceEntries = new Map() + +export function recordBrowserTraceEntry( + payload: Omit, + testId: string = getWorkerState().current?.id || '', +): void { + if (!testId) { + return + } + const entries = browserTraceEntries.get(testId) || [] + entries.push({ + ...payload, + timestamp: Date.now(), + }) + browserTraceEntries.set(testId, entries) +} + +export function consumeBrowserTraceEntries(testId: string): BrowserTraceEntry[] { + const entries = browserTraceEntries.get(testId) || [] + browserTraceEntries.delete(testId) + return entries +} diff --git a/packages/runner/src/types/tasks.ts b/packages/runner/src/types/tasks.ts index b30e04b015b4..f70e6fda67ab 100644 --- a/packages/runner/src/types/tasks.ts +++ b/packages/runner/src/types/tasks.ts @@ -1358,6 +1358,30 @@ export interface VisualRegressionArtifact extends TestArtifactBase { attachments: VisualRegressionArtifactAttachment[] } +export interface BrowserTraceArtifactAttachment extends TestAttachment { + name: string +} + +// TODO: silly +export interface BrowserTraceArtifactStep { + kind: 'mark' | 'group' | 'retry' + name: string + timestamp: number + stack?: string + selector?: string +} + +/** + * @experimental + * + * Artifact type for browser trace metadata and payload attachments. + */ +export interface BrowserTraceArtifact extends TestArtifactBase { + type: 'internal:browserTrace' + kind: 'trace2' + entries: BrowserTraceArtifactStep[] +} + interface FailureScreenshotArtifactAttachment extends TestAttachment { path: string /** Original file system path to the screenshot, before attachment resolution */ @@ -1457,7 +1481,8 @@ export interface TestArtifactRegistry {} * This type automatically includes all artifacts registered via {@link TestArtifactRegistry}. */ export type TestArtifact - = | FailureScreenshotArtifact + = | BrowserTraceArtifact + | FailureScreenshotArtifact | TestAnnotationArtifact | VisualRegressionArtifact | TestArtifactRegistry[keyof TestArtifactRegistry] diff --git a/packages/ui/client/components/artifacts/Artifacts.vue b/packages/ui/client/components/artifacts/Artifacts.vue index 4dc1da6f389f..df37123bc191 100644 --- a/packages/ui/client/components/artifacts/Artifacts.vue +++ b/packages/ui/client/components/artifacts/Artifacts.vue @@ -3,6 +3,7 @@ import type { RunnerTestCase, TestArtifact } from 'vitest' import type { Component } from 'vue' import { computed } from 'vue' import { getLocationString, openLocation } from '~/composables/location' +import TraceView from '../trace/TraceView.vue' import VisualRegression from './visual-regression/VisualRegression.vue' const { test } = defineProps<{ test: RunnerTestCase }>() @@ -18,6 +19,17 @@ const handledArtifacts = computed(() => { for (const artifact of test.artifacts) { switch (artifact.type) { + case 'internal:browserTrace': { + if (artifact.kind === 'trace2') { + handledArtifacts.push({ + artifact, + component: TraceView, + props: { trace: artifact } satisfies ComponentProps, + }) + } + + continue + } case 'internal:toMatchScreenshot': { if (artifact.kind === 'visual-regression') { handledArtifacts.push({ diff --git a/packages/ui/client/components/trace/TraceList.vue b/packages/ui/client/components/trace/TraceList.vue new file mode 100644 index 000000000000..337ee7ff4692 --- /dev/null +++ b/packages/ui/client/components/trace/TraceList.vue @@ -0,0 +1,95 @@ + + + diff --git a/packages/ui/client/components/trace/TraceView.vue b/packages/ui/client/components/trace/TraceView.vue new file mode 100644 index 000000000000..7fd46cc21e6f --- /dev/null +++ b/packages/ui/client/components/trace/TraceView.vue @@ -0,0 +1,35 @@ + + + From 1e08082d2c6f880ad86e7d1fb42651eca96e8de7 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 8 Apr 2026 18:23:27 +0900 Subject: [PATCH 002/118] wip: de-slop --- packages/browser/src/client/tester/context.ts | 2 - .../src/client/tester/expect-element.ts | 1 - .../src/client/tester/locators/index.ts | 1 - packages/browser/src/client/tester/runner.ts | 3 - .../browser/src/client/tester/trace-state.ts | 2 - packages/runner/src/types/tasks.ts | 7 -- .../client/components/artifacts/Artifacts.vue | 13 +-- .../ui/client/components/trace/TraceList.vue | 95 ------------------- .../ui/client/components/trace/TraceView.vue | 34 ++----- 9 files changed, 14 insertions(+), 144 deletions(-) delete mode 100644 packages/ui/client/components/trace/TraceList.vue diff --git a/packages/browser/src/client/tester/context.ts b/packages/browser/src/client/tester/context.ts index 598c27dc2ad6..8a4e14fd8158 100644 --- a/packages/browser/src/client/tester/context.ts +++ b/packages/browser/src/client/tester/context.ts @@ -367,7 +367,6 @@ export const page: BrowserPage = { return ensureAwaited(async (error) => { if (hasActiveTrace) { recordBrowserTraceEntry({ - kind: 'group', name, stack: options?.stack ?? error?.stack, }) @@ -397,7 +396,6 @@ export const page: BrowserPage = { return ensureAwaited((error) => { recordBrowserTraceEntry({ - kind: 'mark', name, stack: bodyOrOptions?.stack ?? error?.stack, }) diff --git a/packages/browser/src/client/tester/expect-element.ts b/packages/browser/src/client/tester/expect-element.ts index daa5c2059435..d2e4c231d7a3 100644 --- a/packages/browser/src/client/tester/expect-element.ts +++ b/packages/browser/src/client/tester/expect-element.ts @@ -69,7 +69,6 @@ function element(elementOrL ? undefined : elementOrLocator.selector recordBrowserTraceEntry({ - kind: 'mark', name: traceName, selector, stack: sourceError.stack, diff --git a/packages/browser/src/client/tester/locators/index.ts b/packages/browser/src/client/tester/locators/index.ts index 8028793a5482..2b6695e82950 100644 --- a/packages/browser/src/client/tester/locators/index.ts +++ b/packages/browser/src/client/tester/locators/index.ts @@ -210,7 +210,6 @@ export abstract class Locator { } return ensureAwaited((error) => { recordBrowserTraceEntry({ - kind: 'mark', name, selector: this.selector, stack: options?.stack ?? error?.stack, diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index 4d10e379aa3d..1de35a1c8c4f 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -111,9 +111,7 @@ export function createBrowserRunner( if (!getBrowserState().activeTraceTaskIds.has(test.id)) { return } - // TODO: silly. not the entry itself, but retry should just isolate traces. recordBrowserTraceEntry({ - kind: 'retry', name: `onAfterRetryTask [${test.result?.state}]`, stack: test.result?.errors?.[0].stack, }, test.id) @@ -155,7 +153,6 @@ export function createBrowserRunner( if (traces2.length) { await recordArtifact(task, { type: 'internal:browserTrace', - kind: 'trace2', entries: traces2, } satisfies BrowserTraceArtifact) } diff --git a/packages/browser/src/client/tester/trace-state.ts b/packages/browser/src/client/tester/trace-state.ts index 76da69df7ad8..40b158399b83 100644 --- a/packages/browser/src/client/tester/trace-state.ts +++ b/packages/browser/src/client/tester/trace-state.ts @@ -1,8 +1,6 @@ import { getWorkerState } from '../utils' export interface BrowserTraceEntry { - // TODO: silly - kind: 'mark' | 'group' | 'retry' name: string timestamp: number stack?: string diff --git a/packages/runner/src/types/tasks.ts b/packages/runner/src/types/tasks.ts index f70e6fda67ab..d117f04e7d39 100644 --- a/packages/runner/src/types/tasks.ts +++ b/packages/runner/src/types/tasks.ts @@ -1358,13 +1358,7 @@ export interface VisualRegressionArtifact extends TestArtifactBase { attachments: VisualRegressionArtifactAttachment[] } -export interface BrowserTraceArtifactAttachment extends TestAttachment { - name: string -} - -// TODO: silly export interface BrowserTraceArtifactStep { - kind: 'mark' | 'group' | 'retry' name: string timestamp: number stack?: string @@ -1378,7 +1372,6 @@ export interface BrowserTraceArtifactStep { */ export interface BrowserTraceArtifact extends TestArtifactBase { type: 'internal:browserTrace' - kind: 'trace2' entries: BrowserTraceArtifactStep[] } diff --git a/packages/ui/client/components/artifacts/Artifacts.vue b/packages/ui/client/components/artifacts/Artifacts.vue index df37123bc191..3fefc7e9c0e0 100644 --- a/packages/ui/client/components/artifacts/Artifacts.vue +++ b/packages/ui/client/components/artifacts/Artifacts.vue @@ -20,14 +20,11 @@ const handledArtifacts = computed(() => { for (const artifact of test.artifacts) { switch (artifact.type) { case 'internal:browserTrace': { - if (artifact.kind === 'trace2') { - handledArtifacts.push({ - artifact, - component: TraceView, - props: { trace: artifact } satisfies ComponentProps, - }) - } - + handledArtifacts.push({ + artifact, + component: TraceView, + props: { trace: artifact } satisfies ComponentProps, + }) continue } case 'internal:toMatchScreenshot': { diff --git a/packages/ui/client/components/trace/TraceList.vue b/packages/ui/client/components/trace/TraceList.vue deleted file mode 100644 index 337ee7ff4692..000000000000 --- a/packages/ui/client/components/trace/TraceList.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - diff --git a/packages/ui/client/components/trace/TraceView.vue b/packages/ui/client/components/trace/TraceView.vue index 7fd46cc21e6f..3435758e5eaf 100644 --- a/packages/ui/client/components/trace/TraceView.vue +++ b/packages/ui/client/components/trace/TraceView.vue @@ -1,35 +1,19 @@ From 250e24cfd970f11a6c3b551623680eec042df22e Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 8 Apr 2026 18:26:28 +0900 Subject: [PATCH 003/118] wip: de-slop --- packages/browser/src/client/tester/context.ts | 2 +- .../browser/src/client/tester/expect-element.ts | 2 +- .../browser/src/client/tester/locators/index.ts | 2 +- packages/browser/src/client/tester/runner.ts | 7 ++----- packages/browser/src/client/tester/trace-state.ts | 15 ++++++--------- packages/runner/src/types.ts | 2 ++ packages/runner/src/types/tasks.ts | 1 + packages/ui/client/components/trace/TraceView.vue | 2 +- 8 files changed, 15 insertions(+), 18 deletions(-) diff --git a/packages/browser/src/client/tester/context.ts b/packages/browser/src/client/tester/context.ts index 8a4e14fd8158..4919ec26bd66 100644 --- a/packages/browser/src/client/tester/context.ts +++ b/packages/browser/src/client/tester/context.ts @@ -19,8 +19,8 @@ import type { Locator as LocatorAPI } from './locators/index' import { vi } from 'vitest' import { __INTERNAL, stringify } from 'vitest/internal/browser' import { ensureAwaited, getBrowserState, getWorkerState } from '../utils' -import { recordBrowserTraceEntry } from './trace-state' import { convertToSelector, isLocator, processTimeoutOptions, resolveUserEventWheelOptions } from './tester-utils' +import { recordBrowserTraceEntry } from './trace-state' // this file should not import anything directly, only types and utils diff --git a/packages/browser/src/client/tester/expect-element.ts b/packages/browser/src/client/tester/expect-element.ts index d2e4c231d7a3..0fcef63b97d7 100644 --- a/packages/browser/src/client/tester/expect-element.ts +++ b/packages/browser/src/client/tester/expect-element.ts @@ -4,8 +4,8 @@ import { chai, expect } from 'vitest' import { getType } from 'vitest/internal/browser' import { getBrowserState, getWorkerState } from '../utils' import { matchers } from './expect' -import { recordBrowserTraceEntry } from './trace-state' import { processTimeoutOptions } from './tester-utils' +import { recordBrowserTraceEntry } from './trace-state' const kLocator = Symbol.for('$$vitest:locator') diff --git a/packages/browser/src/client/tester/locators/index.ts b/packages/browser/src/client/tester/locators/index.ts index 2b6695e82950..e98cd1e368cb 100644 --- a/packages/browser/src/client/tester/locators/index.ts +++ b/packages/browser/src/client/tester/locators/index.ts @@ -28,8 +28,8 @@ import { import { page, server, utils } from 'vitest/browser' import { __INTERNAL, getSafeTimers } from 'vitest/internal/browser' import { ensureAwaited, getBrowserState, getWorkerState } from '../../utils' -import { recordBrowserTraceEntry } from '../trace-state' import { escapeForTextSelector, isLocator, processTimeoutOptions, resolveUserEventWheelOptions } from '../tester-utils' +import { recordBrowserTraceEntry } from '../trace-state' export { ensureAwaited } from '../../utils' export { convertElementToCssSelector, getIframeScale, processTimeoutOptions } from '../tester-utils' diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index 1de35a1c8c4f..659bc8bd8d97 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -32,7 +32,7 @@ import { createStackString, parseStacktrace } from '../../../../utils/src/source import { getBrowserState, getWorkerState, moduleRunner } from '../utils' import { rpc } from './rpc' import { VitestBrowserSnapshotEnvironment } from './snapshot' -import { consumeBrowserTraceEntries, recordBrowserTraceEntry } from './trace-state' +import { consumeBrowserTraceEntries } from './trace-state' interface BrowserRunnerOptions { config: SerializedConfig @@ -111,10 +111,6 @@ export function createBrowserRunner( if (!getBrowserState().activeTraceTaskIds.has(test.id)) { return } - recordBrowserTraceEntry({ - name: `onAfterRetryTask [${test.result?.state}]`, - stack: test.result?.errors?.[0].stack, - }, test.id) await this.commands.triggerCommand('__vitest_markTrace', [{ name: `onAfterRetryTask [${test.result?.state}]`, stack: test.result?.errors?.[0].stack, @@ -144,6 +140,7 @@ export function createBrowserRunner( ) } else { + // TODO: separate group entries by retries await this.commands.triggerCommand( '__vitest_annotateTraces', [{ testId: task.id, traces }], diff --git a/packages/browser/src/client/tester/trace-state.ts b/packages/browser/src/client/tester/trace-state.ts index 40b158399b83..9dbf85913193 100644 --- a/packages/browser/src/client/tester/trace-state.ts +++ b/packages/browser/src/client/tester/trace-state.ts @@ -1,16 +1,13 @@ +import type { BrowserTraceArtifactStep } from '@vitest/runner' import { getWorkerState } from '../utils' -export interface BrowserTraceEntry { - name: string - timestamp: number - stack?: string - selector?: string -} +// TODO: review slop (NEVER REMOVE COMMENT) -const browserTraceEntries = new Map() +const browserTraceEntries = new Map() export function recordBrowserTraceEntry( - payload: Omit, + payload: Omit, + // TODO: silly defensive? testId: string = getWorkerState().current?.id || '', ): void { if (!testId) { @@ -24,7 +21,7 @@ export function recordBrowserTraceEntry( browserTraceEntries.set(testId, entries) } -export function consumeBrowserTraceEntries(testId: string): BrowserTraceEntry[] { +export function consumeBrowserTraceEntries(testId: string): BrowserTraceArtifactStep[] { const entries = browserTraceEntries.get(testId) || [] browserTraceEntries.delete(testId) return entries diff --git a/packages/runner/src/types.ts b/packages/runner/src/types.ts index 4b79bd876afa..84fff5a55ec9 100644 --- a/packages/runner/src/types.ts +++ b/packages/runner/src/types.ts @@ -47,6 +47,8 @@ export type { TaskResultPack, TaskState, TaskUpdateEvent, + BrowserTraceArtifact, + BrowserTraceArtifactStep, Test, TestAnnotation, TestAnnotationArtifact, diff --git a/packages/runner/src/types/tasks.ts b/packages/runner/src/types/tasks.ts index d117f04e7d39..6b5ef5230062 100644 --- a/packages/runner/src/types/tasks.ts +++ b/packages/runner/src/types/tasks.ts @@ -1358,6 +1358,7 @@ export interface VisualRegressionArtifact extends TestArtifactBase { attachments: VisualRegressionArtifactAttachment[] } +// TODO: design export interface BrowserTraceArtifactStep { name: string timestamp: number diff --git a/packages/ui/client/components/trace/TraceView.vue b/packages/ui/client/components/trace/TraceView.vue index 3435758e5eaf..9c8748c46a7f 100644 --- a/packages/ui/client/components/trace/TraceView.vue +++ b/packages/ui/client/components/trace/TraceView.vue @@ -1,5 +1,5 @@