Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(new-trace): Updating empty state copy #87217

Merged
merged 3 commits into from
Mar 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions static/app/views/performance/newTraceDetails/trace.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,12 @@ describe('trace view', () => {
expect(await screen.findByText(/we failed to load your trace/i)).toBeInTheDocument();
});

it('renders empty state', async () => {
it('renders empty state for successfully ingested trace', async () => {
// set timestamp to 3 minutes ago
const threeMinutesAgoInSeconds = Math.floor(
new Date(Date.now() - 3 * 60 * 1000).getTime() / 1000
);

mockPerformanceSubscriptionDetailsResponse();
mockTraceResponse({
body: {
Expand All @@ -921,12 +926,43 @@ describe('trace view', () => {
mockTraceTagsResponse();
mockEventsResponse();

render(<TraceView />, {router});
window.location.search = `?timestamp=${threeMinutesAgoInSeconds.toString()}`;
render(<TraceView />, {
router,
});
expect(
await screen.findByText(/trace does not contain any data/i)
).toBeInTheDocument();
});

it('renders empty state for yet to be ingested trace', async () => {
// set timestamp to 1 minute ago
const oneMinuteAgoInSeconds = Math.floor(
new Date(Date.now() - 1 * 60 * 1000).getTime() / 1000
);

mockPerformanceSubscriptionDetailsResponse();
mockTraceResponse({
body: {
transactions: [],
orphan_errors: [],
},
});
mockTraceMetaResponse();
mockTraceTagsResponse();
mockEventsResponse();

window.location.search = `?timestamp=${oneMinuteAgoInSeconds.toString()}`;
render(<TraceView />, {
router,
});
expect(
await screen.findByText(
/We could still be ingesting this trace. Please wait a few seconds and refresh./i
)
).toBeInTheDocument();
});

describe('pageload', () => {
it('scrolls to trace root', async () => {
mockQueryString('?node=trace-root');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import styled from '@emotion/styled';
import useFeedbackWidget from 'sentry/components/feedback/widget/useFeedbackWidget';
import LoadingIndicator from 'sentry/components/loadingIndicator';
import {t} from 'sentry/locale';
import {useTraceQueryParams} from 'sentry/views/performance/newTraceDetails/useTraceQueryParams';

function TraceLoading() {
return (
Expand Down Expand Up @@ -43,9 +44,22 @@ function TraceEmpty() {
const linkref = useRef<HTMLAnchorElement>(null);
const feedback = useFeedbackWidget({buttonRef: linkref});

const traceQueryParams = useTraceQueryParams();
const timestamp = traceQueryParams.timestamp;

// Traces take longer to ingest than spans, we could click on the id of a span
// and be navigated to a trace that doesn't contain any data yet. We add a 2
// minute buffer to account for this.
const message =
timestamp && new Date(timestamp * 1000) >= new Date(Date.now() - 2 * 60 * 1000)
? t(
'We could still be ingesting this trace. Please wait a few seconds and refresh.'
)
: t('This trace does not contain any data.');

return (
<LoadingContainer animate>
<div>{t('This trace does not contain any data?!')}</div>
<div>{message}</div>
<div>
{t('Seeing this often? Send us ')}
{feedback ? (
Expand Down
Loading