header.spec.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {ProjectFixture} from 'sentry-fixture/project';
  3. import {initializeOrg} from 'sentry-test/initializeOrg';
  4. import {act, render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
  5. import type {PlatformKey} from 'sentry/types/project';
  6. import EventView from 'sentry/utils/discover/eventView';
  7. import TransactionHeader from 'sentry/views/performance/transactionSummary/header';
  8. import Tab from 'sentry/views/performance/transactionSummary/tabs';
  9. type InitialOpts = {
  10. features?: string[];
  11. platform?: PlatformKey;
  12. };
  13. function initializeData(opts?: InitialOpts) {
  14. const {features, platform} = opts ?? {};
  15. const project = ProjectFixture({platform});
  16. const organization = OrganizationFixture({
  17. features: features ?? [],
  18. });
  19. const initialData = initializeOrg({
  20. organization,
  21. router: {
  22. location: {
  23. query: {
  24. project: project.id,
  25. },
  26. },
  27. },
  28. projects: [],
  29. });
  30. const router = initialData.router;
  31. const eventView = EventView.fromSavedQuery({
  32. id: undefined,
  33. version: 2,
  34. name: '',
  35. fields: ['transaction.status'], // unused fields
  36. projects: [parseInt(project.id, 10)],
  37. });
  38. return {
  39. project,
  40. organization,
  41. router,
  42. eventView,
  43. };
  44. }
  45. describe('Performance > Transaction Summary Header', function () {
  46. beforeEach(function () {
  47. MockApiClient.clearMockResponses();
  48. MockApiClient.addMockResponse({
  49. url: '/organizations/org-slug/replay-count/',
  50. body: {},
  51. });
  52. });
  53. it('should render web vitals tab when yes', async function () {
  54. const {project, organization, router, eventView} = initializeData();
  55. MockApiClient.addMockResponse({
  56. url: '/organizations/org-slug/events-has-measurements/',
  57. body: {measurements: true},
  58. });
  59. render(
  60. <TransactionHeader
  61. eventView={eventView}
  62. location={router.location}
  63. organization={organization}
  64. projects={[project]}
  65. projectId={project.id}
  66. transactionName="transaction_name"
  67. currentTab={Tab.TRANSACTION_SUMMARY}
  68. hasWebVitals="yes"
  69. />
  70. );
  71. expect(await screen.findByRole('tab', {name: 'Web Vitals'})).toBeInTheDocument();
  72. });
  73. it('should not render web vitals tab when hasWebVitals=no', async function () {
  74. const {project, organization, router, eventView} = initializeData();
  75. MockApiClient.addMockResponse({
  76. url: '/organizations/org-slug/events-has-measurements/',
  77. body: {measurements: true},
  78. });
  79. render(
  80. <TransactionHeader
  81. eventView={eventView}
  82. location={router.location}
  83. organization={organization}
  84. projects={[project]}
  85. projectId={project.id}
  86. transactionName="transaction_name"
  87. currentTab={Tab.TRANSACTION_SUMMARY}
  88. hasWebVitals="no"
  89. />
  90. );
  91. await act(tick);
  92. expect(screen.queryByRole('tab', {name: 'Web Vitals'})).not.toBeInTheDocument();
  93. });
  94. it('should render web vitals tab when maybe and is frontend platform', async function () {
  95. const {project, organization, router, eventView} = initializeData({
  96. platform: 'javascript',
  97. });
  98. MockApiClient.addMockResponse({
  99. url: '/organizations/org-slug/events-has-measurements/',
  100. body: {measurements: true},
  101. });
  102. render(
  103. <TransactionHeader
  104. eventView={eventView}
  105. location={router.location}
  106. organization={organization}
  107. projects={[project]}
  108. projectId={project.id}
  109. transactionName="transaction_name"
  110. currentTab={Tab.TRANSACTION_SUMMARY}
  111. hasWebVitals="maybe"
  112. />
  113. );
  114. expect(await screen.findByRole('tab', {name: 'Web Vitals'})).toBeInTheDocument();
  115. });
  116. it('should render web vitals tab when maybe and has measurements', async function () {
  117. const {project, organization, router, eventView} = initializeData();
  118. const eventHasMeasurementsMock = MockApiClient.addMockResponse({
  119. url: '/organizations/org-slug/events-has-measurements/',
  120. body: {measurements: true},
  121. });
  122. render(
  123. <TransactionHeader
  124. eventView={eventView}
  125. location={router.location}
  126. organization={organization}
  127. projects={[project]}
  128. projectId={project.id}
  129. transactionName="transaction_name"
  130. currentTab={Tab.TRANSACTION_SUMMARY}
  131. hasWebVitals="maybe"
  132. />
  133. );
  134. await waitFor(() => expect(eventHasMeasurementsMock).toHaveBeenCalled());
  135. expect(screen.getByRole('tab', {name: 'Web Vitals'})).toBeInTheDocument();
  136. });
  137. it('should not render web vitals tab when maybe and has no measurements', async function () {
  138. const {project, organization, router, eventView} = initializeData();
  139. const eventHasMeasurementsMock = MockApiClient.addMockResponse({
  140. url: '/organizations/org-slug/events-has-measurements/',
  141. body: {measurements: false},
  142. });
  143. MockApiClient.addMockResponse({
  144. url: '/organizations/org-slug/replay-count/',
  145. body: {},
  146. });
  147. render(
  148. <TransactionHeader
  149. eventView={eventView}
  150. location={router.location}
  151. organization={organization}
  152. projects={[project]}
  153. projectId={project.id}
  154. transactionName="transaction_name"
  155. currentTab={Tab.TRANSACTION_SUMMARY}
  156. hasWebVitals="maybe"
  157. />
  158. );
  159. await waitFor(() => expect(eventHasMeasurementsMock).toHaveBeenCalled());
  160. expect(screen.queryByRole('tab', {name: 'Web Vitals'})).not.toBeInTheDocument();
  161. });
  162. it('should render spans tab with feature', async function () {
  163. const {project, organization, router, eventView} = initializeData({});
  164. MockApiClient.addMockResponse({
  165. url: '/organizations/org-slug/events-has-measurements/',
  166. body: {measurements: true},
  167. });
  168. render(
  169. <TransactionHeader
  170. eventView={eventView}
  171. location={router.location}
  172. organization={organization}
  173. projects={[project]}
  174. projectId={project.id}
  175. transactionName="transaction_name"
  176. currentTab={Tab.TRANSACTION_SUMMARY}
  177. hasWebVitals="yes"
  178. />
  179. );
  180. expect(await screen.findByRole('tab', {name: 'Spans'})).toBeInTheDocument();
  181. });
  182. });