Skip to content

Commit 456a860

Browse files
authored
Merge branch 'main' into feat/mcwp-574-yarn-cache-prepare-job
2 parents c4ccf09 + 38817db commit 456a860

20 files changed

Lines changed: 1154 additions & 295 deletions

File tree

app/components/UI/AssetOverview/Price/Price.advanced.test.tsx

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ import { AnalyticsEventBuilder } from '../../../../util/analytics/AnalyticsEvent
1111

1212
jest.mock('../../../hooks/useAnalytics/useAnalytics');
1313

14+
const mockTrace = jest.fn();
15+
const mockEndTrace = jest.fn();
16+
17+
jest.mock('../../../../util/trace', () => ({
18+
...jest.requireActual('../../../../util/trace'),
19+
trace: (...args: unknown[]) => mockTrace(...args),
20+
endTrace: (...args: unknown[]) => mockEndTrace(...args),
21+
}));
22+
1423
const mockSetIsChartBeingTouched = jest.fn();
1524
jest.mock('../PriceChart/PriceChart.context', () => ({
1625
usePriceChart: () => ({
@@ -830,4 +839,203 @@ describe('PriceAdvanced', () => {
830839
expect(mockSetIsChartBeingTouched).toHaveBeenCalledWith(false);
831840
});
832841
});
842+
843+
describe('performance tracing', () => {
844+
beforeEach(() => {
845+
mockTrace.mockClear();
846+
mockEndTrace.mockClear();
847+
});
848+
849+
it('starts initial visibility trace when component mounts with advanced chart', () => {
850+
render(<PriceAdvanced {...baseProps} />);
851+
852+
expect(mockTrace).toHaveBeenCalledWith(
853+
expect.objectContaining({
854+
name: expect.stringContaining('Advanced Chart Initial Visible'),
855+
op: expect.stringContaining('token_overview.advanced_chart'),
856+
}),
857+
);
858+
});
859+
860+
it('ends trace when onSkeletonHidden is called with matching series key', () => {
861+
const { getByTestId } = render(<PriceAdvanced {...baseProps} />);
862+
const advancedChart = getByTestId('mock-advanced-chart');
863+
864+
mockEndTrace.mockClear();
865+
866+
act(() => {
867+
advancedChart.props.onSkeletonHidden?.();
868+
});
869+
870+
expect(mockEndTrace).toHaveBeenCalledWith(
871+
expect.objectContaining({
872+
name: expect.stringContaining('Advanced Chart Initial Visible'),
873+
}),
874+
);
875+
});
876+
877+
it('ends trace with error data when onError is called', () => {
878+
const { getByTestId } = render(<PriceAdvanced {...baseProps} />);
879+
const advancedChart = getByTestId('mock-advanced-chart');
880+
881+
mockEndTrace.mockClear();
882+
883+
act(() => {
884+
advancedChart.props.onError?.('WebView failed to load');
885+
});
886+
887+
expect(mockEndTrace).toHaveBeenCalledWith(
888+
expect.objectContaining({
889+
name: expect.stringContaining('Advanced Chart Initial Visible'),
890+
data: expect.objectContaining({
891+
errorMessage: 'WebView failed to load',
892+
}),
893+
}),
894+
);
895+
});
896+
897+
it('starts time range visibility trace when time range changes', () => {
898+
const { getByTestId } = render(<PriceAdvanced {...baseProps} />);
899+
900+
mockTrace.mockClear();
901+
902+
act(() => {
903+
fireEvent.press(getByTestId('select-1W'));
904+
});
905+
906+
expect(mockTrace).toHaveBeenCalledWith(
907+
expect.objectContaining({
908+
name: expect.stringContaining('Time Range Visible'),
909+
op: expect.stringContaining('time_range'),
910+
}),
911+
);
912+
});
913+
914+
it('supersedes previous trace when series key changes before skeleton hidden', () => {
915+
const { getByTestId } = render(<PriceAdvanced {...baseProps} />);
916+
917+
mockEndTrace.mockClear();
918+
919+
act(() => {
920+
fireEvent.press(getByTestId('select-1W'));
921+
});
922+
923+
expect(mockEndTrace).toHaveBeenCalledWith(
924+
expect.objectContaining({
925+
data: expect.objectContaining({
926+
superseded: true,
927+
}),
928+
}),
929+
);
930+
});
931+
932+
it('ends trace with fallbackToLegacy when switching to legacy chart', () => {
933+
const { rerender } = render(<PriceAdvanced {...baseProps} />);
934+
935+
mockEndTrace.mockClear();
936+
937+
mockUseOHLCVChart.mockReturnValueOnce({
938+
ohlcvData: [],
939+
isLoading: false,
940+
error: undefined,
941+
hasMore: false,
942+
nextCursor: null,
943+
hasEmptyData: true,
944+
});
945+
946+
rerender(<PriceAdvanced {...baseProps} />);
947+
948+
expect(mockEndTrace).toHaveBeenCalledWith(
949+
expect.objectContaining({
950+
data: expect.objectContaining({
951+
fallbackToLegacy: true,
952+
}),
953+
}),
954+
);
955+
});
956+
957+
it('includes assetId in trace data when available', () => {
958+
mockTrace.mockClear();
959+
960+
render(<PriceAdvanced {...baseProps} />);
961+
962+
expect(mockTrace).toHaveBeenCalledWith(
963+
expect.objectContaining({
964+
data: expect.objectContaining({
965+
assetId: expect.any(String),
966+
}),
967+
}),
968+
);
969+
});
970+
971+
it('does not start trace when falling back to legacy chart immediately', () => {
972+
mockTrace.mockClear();
973+
974+
mockUseOHLCVChart.mockReturnValueOnce({
975+
ohlcvData: [],
976+
isLoading: false,
977+
error: undefined,
978+
hasMore: false,
979+
nextCursor: null,
980+
hasEmptyData: true,
981+
});
982+
983+
render(<PriceAdvanced {...baseProps} />);
984+
985+
expect(mockTrace).not.toHaveBeenCalled();
986+
});
987+
988+
it('ends trace with unmounted flag when component unmounts with open trace', () => {
989+
const { unmount } = render(<PriceAdvanced {...baseProps} />);
990+
991+
mockEndTrace.mockClear();
992+
993+
unmount();
994+
995+
expect(mockEndTrace).toHaveBeenCalledWith(
996+
expect.objectContaining({
997+
name: expect.stringContaining('Advanced Chart Initial Visible'),
998+
data: expect.objectContaining({
999+
unmounted: true,
1000+
}),
1001+
}),
1002+
);
1003+
});
1004+
1005+
it('does not end trace on unmount when trace was already completed', () => {
1006+
const { getByTestId, unmount } = render(<PriceAdvanced {...baseProps} />);
1007+
const advancedChart = getByTestId('mock-advanced-chart');
1008+
1009+
act(() => {
1010+
advancedChart.props.onSkeletonHidden?.();
1011+
});
1012+
1013+
mockEndTrace.mockClear();
1014+
1015+
unmount();
1016+
1017+
expect(mockEndTrace).not.toHaveBeenCalled();
1018+
});
1019+
1020+
it('truncates error message to 200 characters', () => {
1021+
const { getByTestId } = render(<PriceAdvanced {...baseProps} />);
1022+
const advancedChart = getByTestId('mock-advanced-chart');
1023+
1024+
mockEndTrace.mockClear();
1025+
1026+
const longError = 'A'.repeat(300);
1027+
1028+
act(() => {
1029+
advancedChart.props.onError?.(longError);
1030+
});
1031+
1032+
expect(mockEndTrace).toHaveBeenCalledWith(
1033+
expect.objectContaining({
1034+
data: expect.objectContaining({
1035+
errorMessage: 'A'.repeat(200),
1036+
}),
1037+
}),
1038+
);
1039+
});
1040+
});
8331041
});

0 commit comments

Comments
 (0)