Skip to content
Open
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
1 change: 0 additions & 1 deletion static/app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2141,7 +2141,6 @@ function buildRoutes(): RouteObject[] {
{
path: 'vitaldetail/',
component: make(() => import('sentry/views/performance/vitalDetail')),
deprecatedRouteProps: true,
},
traceView,
...insightsRedirectObjects,
Expand Down
236 changes: 108 additions & 128 deletions static/app/views/performance/vitalDetail/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,25 @@ import {textWithMarkupMatcher} from 'sentry-test/utils';

import ProjectsStore from 'sentry/stores/projectsStore';
import TeamStore from 'sentry/stores/teamStore';
import type {InjectedRouter} from 'sentry/types/legacyReactRouter';
import {WebVital} from 'sentry/utils/fields';
import {Browser} from 'sentry/utils/performance/vitals/constants';
import {DEFAULT_STATS_PERIOD} from 'sentry/views/performance/data';
import VitalDetail from 'sentry/views/performance/vitalDetail';
import {vitalSupportedBrowsers} from 'sentry/views/performance/vitalDetail/utils';

const mockNavigate = jest.fn();
jest.mock('sentry/utils/useNavigate', () => ({
useNavigate: () => mockNavigate,
}));

const organization = OrganizationFixture({
features: ['discover-basic', 'performance-view'],
});

const {
organization: org,
project,
router,
} = initializeOrg({
const {organization: org, project} = initializeOrg({
organization,
router: {
location: {
query: {
project: '1',
},
},
},
});

function TestComponent(props: {router?: InjectedRouter} = {}) {
return (
<VitalDetail
location={props.router?.location ?? router.location}
router={props.router ?? router}
params={{}}
route={{}}
routes={[]}
routeParams={{}}
/>
);
}

const testSupportedBrowserRendering = (webVital: WebVital) => {
Object.values(Browser).forEach(browser => {
const browserElement = screen.getByText(browser);
Expand Down Expand Up @@ -224,10 +204,16 @@ describe('Performance > VitalDetail', () => {
});

it('renders basic UI elements', async () => {
render(<TestComponent />, {
router,
render(<VitalDetail />, {
organization: org,
deprecatedRouterMocks: true,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
project: '1',
},
},
},
});

// It shows a search bar
Expand All @@ -252,25 +238,34 @@ describe('Performance > VitalDetail', () => {
});

it('triggers a navigation on search', async () => {
render(<TestComponent />, {
router,
render(<VitalDetail />, {
organization: org,
deprecatedRouterMocks: true,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
project: '1',
},
},
},
});

// Fill out the search box, and submit it.
// Clear any navigation calls from initialization
mockNavigate.mockClear();

// Fill out the search box, and submit it
await userEvent.click(
await screen.findByPlaceholderText('Search for events, users, tags, and more')
);
await userEvent.paste('user.email:uhoh*');

// Check the navigation.
// Check the navigation
await waitFor(() => {
expect(router.push).toHaveBeenCalledTimes(1);
expect(mockNavigate).toHaveBeenCalledTimes(1);
});

expect(router.push).toHaveBeenCalledWith({
pathname: undefined,
expect(mockNavigate).toHaveBeenCalledWith({
pathname: '/performance/vitaldetail/',
query: {
project: '1',
statsPeriod: '14d',
Expand All @@ -280,20 +275,16 @@ describe('Performance > VitalDetail', () => {
});

it('applies conditions when linking to transaction summary', async () => {
const newRouter = {
...router,
location: {
...router.location,
query: {
query: 'sometag:value',
render(<VitalDetail />, {
organization: org,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
query: 'sometag:value',
},
},
},
};

render(<TestComponent router={newRouter} />, {
router: newRouter,
organization: org,
deprecatedRouterMocks: true,
});

expect(
Expand All @@ -304,7 +295,7 @@ describe('Performance > VitalDetail', () => {
await screen.findByLabelText('See transaction summary of the transaction something')
);

expect(newRouter.push).toHaveBeenCalledWith({
expect(mockNavigate).toHaveBeenCalledWith({
pathname: `/organizations/${organization.slug}/insights/summary/`,
query: {
transaction: 'something',
Expand All @@ -325,30 +316,29 @@ describe('Performance > VitalDetail', () => {
});

it('check CLS', async () => {
const newRouter = {
...router,
location: {
...router.location,
query: {
query: 'anothertag:value',
vitalName: 'measurements.cls',
render(<VitalDetail />, {
organization: org,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
query: 'anothertag:value',
vitalName: 'measurements.cls',
},
},
},
};

render(<TestComponent router={newRouter} />, {
router: newRouter,
organization: org,
deprecatedRouterMocks: true,
});

expect(await screen.findByText('Cumulative Layout Shift')).toBeInTheDocument();

// Check cells are not in ms
expect(screen.getByText('0.215').closest('td')).toBeInTheDocument();

await userEvent.click(
await screen.findByLabelText('See transaction summary of the transaction something')
);

expect(newRouter.push).toHaveBeenCalledWith({
expect(mockNavigate).toHaveBeenCalledWith({
pathname: `/organizations/${organization.slug}/insights/summary/`,
query: {
transaction: 'something',
Expand All @@ -366,29 +356,25 @@ describe('Performance > VitalDetail', () => {
trendColumn: undefined,
},
});

// Check cells are not in ms
expect(screen.getByText('0.215').closest('td')).toBeInTheDocument();
});

it('can switch vitals with dropdown menu', async () => {
const newRouter = {
...router,
location: {
...router.location,
query: {
project: 1,
query: 'tag:value',
render(<VitalDetail />, {
organization: org,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
project: '1',
query: 'tag:value',
},
},
},
};

render(<TestComponent router={newRouter} />, {
router: newRouter,
organization: org,
deprecatedRouterMocks: true,
});

// Clear any navigation calls from initialization
mockNavigate.mockClear();

const button = screen.getByRole('button', {name: /web vitals: lcp/i});
expect(button).toBeInTheDocument();
await userEvent.click(button);
Expand All @@ -397,22 +383,25 @@ describe('Performance > VitalDetail', () => {
expect(menuItem).toBeInTheDocument();
await userEvent.click(menuItem);

expect(newRouter.push).toHaveBeenCalledTimes(1);
expect(newRouter.push).toHaveBeenCalledWith({
pathname: undefined,
expect(mockNavigate).toHaveBeenCalledTimes(1);
expect(mockNavigate).toHaveBeenCalledWith({
pathname: '/performance/vitaldetail/',
query: {
project: 1,
project: '1',
query: 'tag:value',
vitalName: 'measurements.fcp',
},
});
});

it('renders LCP vital correctly', async () => {
render(<TestComponent />, {
router,
render(<VitalDetail />, {
organization: org,
deprecatedRouterMocks: true,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
},
},
});

expect(await screen.findByText('Largest Contentful Paint')).toBeInTheDocument();
Expand All @@ -425,83 +414,74 @@ describe('Performance > VitalDetail', () => {
});

it('correctly renders which browsers support LCP', async () => {
render(<TestComponent />, {
router,
render(<VitalDetail />, {
organization: org,
deprecatedRouterMocks: true,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
},
},
});

expect(await screen.findAllByText(/Largest Contentful Paint/)).toHaveLength(2);
testSupportedBrowserRendering(WebVital.LCP);
});

it('correctly renders which browsers support CLS', async () => {
const newRouter = {
...router,
location: {
...router.location,
query: {
vitalName: 'measurements.cls',
render(<VitalDetail />, {
organization: org,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
vitalName: 'measurements.cls',
},
},
},
};

render(<TestComponent router={newRouter} />, {
router,
organization: org,
deprecatedRouterMocks: true,
});

expect(await screen.findAllByText(/Cumulative Layout Shift/)).toHaveLength(2);
testSupportedBrowserRendering(WebVital.CLS);
});

it('correctly renders which browsers support FCP', async () => {
const newRouter = {
...router,
location: {
...router.location,
query: {
vitalName: 'measurements.fcp',
},
},
};

MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/events/`,
body: [],
});

render(<TestComponent router={newRouter} />, {
router,
render(<VitalDetail />, {
organization: org,
deprecatedRouterMocks: true,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
vitalName: 'measurements.fcp',
},
},
},
});

expect(await screen.findAllByText(/First Contentful Paint/)).toHaveLength(2);
testSupportedBrowserRendering(WebVital.FCP);
});

it('correctly renders which browsers support FID', async () => {
const newRouter = {
...router,
location: {
...router.location,
query: {
vitalName: 'measurements.fid',
},
},
};

MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/events/`,
body: [],
});

render(<TestComponent router={newRouter} />, {
router,
render(<VitalDetail />, {
organization: org,
deprecatedRouterMocks: true,
initialRouterConfig: {
location: {
pathname: '/performance/vitaldetail/',
query: {
vitalName: 'measurements.fid',
},
},
},
});

expect(await screen.findAllByText(/First Input Delay/)).toHaveLength(2);
Expand Down
Loading