123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- import React from 'react';
- import moment from 'moment';
- import {initializeData} from 'sentry-test/performance/initializePerformanceData';
- import {act, render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
- import ProjectsStore from 'sentry/stores/projectsStore';
- import {PerformanceChangeExplorer} from 'sentry/views/performance/trends/changeExplorer';
- import {
- COLUMNS,
- MetricsTable,
- renderBodyCell,
- } from 'sentry/views/performance/trends/changeExplorerUtils/metricsTable';
- import {
- NormalizedTrendsTransaction,
- TrendChangeType,
- TrendFunctionField,
- } from 'sentry/views/performance/trends/types';
- import {TRENDS_PARAMETERS} from 'sentry/views/performance/trends/utils';
- async function waitForMockCall(mock: jest.Mock) {
- await waitFor(() => {
- expect(mock).toHaveBeenCalled();
- });
- }
- const transaction: NormalizedTrendsTransaction = {
- aggregate_range_1: 78.2757131147541,
- aggregate_range_2: 110.50465131578949,
- breakpoint: 1687262400,
- project: 'sentry',
- transaction: 'sentry.tasks.store.save_event',
- trend_difference: 32.22893820103539,
- trend_percentage: 1.411736117354651,
- count: 3459,
- received_at: moment(1601251200000),
- };
- describe('Performance > Trends > Performance Change Explorer', function () {
- let eventsMockBefore;
- beforeEach(function () {
- eventsMockBefore = MockApiClient.addMockResponse({
- url: '/organizations/org-slug/events/',
- body: {
- data: [
- {
- 'p95()': 1010.9232499999998,
- 'p50()': 47.34580982348902,
- 'tps()': 3.7226926286168966,
- 'count()': 345,
- },
- ],
- meta: {
- fields: {
- 'p95()': 'duration',
- '950()': 'duration',
- 'tps()': 'number',
- 'count()': 'number',
- },
- units: {
- 'p95()': 'millisecond',
- 'p50()': 'millisecond',
- 'tps()': null,
- 'count()': null,
- },
- isMetricsData: true,
- tips: {},
- dataset: 'metrics',
- },
- },
- });
- });
- afterEach(function () {
- MockApiClient.clearMockResponses();
- act(() => ProjectsStore.reset());
- });
- it('renders basic UI elements', async function () {
- const data = initializeData();
- const statsData = {
- ['/organizations/:orgId/performance/']: {
- data: [],
- order: 0,
- },
- };
- render(
- <PerformanceChangeExplorer
- collapsed={false}
- transaction={transaction}
- onClose={() => {}}
- trendChangeType={TrendChangeType.REGRESSION}
- trendFunction={TrendFunctionField.P50}
- trendParameter={TRENDS_PARAMETERS[0]}
- trendView={data.eventView}
- statsData={statsData}
- isLoading={false}
- organization={data.organization}
- projects={data.projects}
- location={data.location}
- />,
- {
- context: data.routerContext,
- organization: data.organization,
- }
- );
- await waitForMockCall(eventsMockBefore);
- await waitFor(() => {
- expect(screen.getByTestId('pce-header')).toBeInTheDocument();
- expect(screen.getByTestId('pce-graph')).toBeInTheDocument();
- expect(screen.getByTestId('grid-editable')).toBeInTheDocument();
- expect(screen.getAllByTestId('pce-metrics-chart-row-metric')).toHaveLength(4);
- expect(screen.getAllByTestId('pce-metrics-chart-row-before')).toHaveLength(4);
- expect(screen.getAllByTestId('pce-metrics-chart-row-after')).toHaveLength(4);
- expect(screen.getAllByTestId('pce-metrics-chart-row-change')).toHaveLength(4);
- });
- });
- it('shows correct change notation for no change', async () => {
- const data = initializeData();
- render(
- <MetricsTable
- isLoading={false}
- location={data.location}
- trendFunction={TrendFunctionField.P50}
- transaction={transaction}
- trendView={data.eventView}
- organization={data.organization}
- />
- );
- await waitForMockCall(eventsMockBefore);
- await waitFor(() => {
- expect(screen.getAllByText('3.7 ps')).toHaveLength(2);
- expect(screen.getAllByTestId('pce-metrics-text-change')[0]).toHaveTextContent('-');
- });
- });
- it('shows correct change notation for positive change', async () => {
- const data = initializeData();
- render(
- <MetricsTable
- isLoading={false}
- location={data.location}
- trendFunction={TrendFunctionField.P50}
- transaction={transaction}
- trendView={data.eventView}
- organization={data.organization}
- />
- );
- await waitForMockCall(eventsMockBefore);
- await waitFor(() => {
- expect(screen.getAllByTestId('pce-metrics-text-before')[1]).toHaveTextContent(
- '78.3 ms'
- );
- expect(screen.getAllByTestId('pce-metrics-text-after')[1]).toHaveTextContent(
- '110.5 ms'
- );
- expect(screen.getAllByTestId('pce-metrics-text-change')[1]).toHaveTextContent(
- '+41.2%'
- );
- });
- });
- it('shows correct change notation for negative change', async () => {
- const data = initializeData();
- const negativeTransaction = {
- ...transaction,
- aggregate_range_1: 110.50465131578949,
- aggregate_range_2: 78.2757131147541,
- trend_percentage: 0.588263882645349,
- };
- render(
- <MetricsTable
- isLoading={false}
- location={data.location}
- trendFunction={TrendFunctionField.P50}
- transaction={negativeTransaction}
- trendView={data.eventView}
- organization={data.organization}
- />
- );
- await waitForMockCall(eventsMockBefore);
- await waitFor(() => {
- expect(screen.getAllByTestId('pce-metrics-text-after')[1]).toHaveTextContent(
- '78.3 ms'
- );
- expect(screen.getAllByTestId('pce-metrics-text-before')[1]).toHaveTextContent(
- '110.5 ms'
- );
- expect(screen.getAllByTestId('pce-metrics-text-change')[1]).toHaveTextContent(
- '-41.2%'
- );
- });
- });
- it('shows correct change notation for no results', async () => {
- const data = initializeData();
- const nullEventsMock = MockApiClient.addMockResponse({
- url: '/organizations/org-slug/events/',
- body: {
- data: [
- {
- 'p95()': 1010.9232499999998,
- 'p50()': 47.34580982348902,
- 'count()': 345,
- },
- ],
- meta: {
- fields: {
- 'p95()': 'duration',
- '950()': 'duration',
- 'count()': 'number',
- },
- units: {
- 'p95()': 'millisecond',
- 'p50()': 'millisecond',
- 'count()': null,
- },
- isMetricsData: true,
- tips: {},
- dataset: 'metrics',
- },
- },
- });
- render(
- <MetricsTable
- isLoading={false}
- location={data.location}
- trendFunction={TrendFunctionField.P50}
- transaction={transaction}
- trendView={data.eventView}
- organization={data.organization}
- />
- );
- await waitForMockCall(nullEventsMock);
- await waitFor(() => {
- expect(screen.getAllByTestId('pce-metrics-text-after')[0]).toHaveTextContent('-');
- expect(screen.getAllByTestId('pce-metrics-text-before')[0]).toHaveTextContent('-');
- expect(screen.getAllByTestId('pce-metrics-text-change')[0]).toHaveTextContent('-');
- });
- });
- it('returns correct null formatting for change column', () => {
- render(
- <React.Fragment>
- {renderBodyCell(COLUMNS.change, {
- metric: null,
- before: null,
- after: null,
- change: '0%',
- })}
- {renderBodyCell(COLUMNS.change, {
- metric: null,
- before: null,
- after: null,
- change: '+NaN%',
- })}
- {renderBodyCell(COLUMNS.change, {
- metric: null,
- before: null,
- after: null,
- change: '-',
- })}
- </React.Fragment>
- );
- expect(screen.getAllByTestId('pce-metrics-text-change')[0]).toHaveTextContent('-');
- expect(screen.getAllByTestId('pce-metrics-text-change')[1]).toHaveTextContent('-');
- expect(screen.getAllByTestId('pce-metrics-text-change')[2]).toHaveTextContent('-');
- });
- it('returns correct positive formatting for change column', () => {
- render(
- renderBodyCell(COLUMNS.change, {
- metric: null,
- before: null,
- after: null,
- change: '40.3%',
- })
- );
- expect(screen.getByText('+40.3%')).toBeInTheDocument();
- });
- });
|