header.spec.tsx 6.2 KB

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