pageOverview.spec.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
  3. import {useLocation} from 'sentry/utils/useLocation';
  4. import useOrganization from 'sentry/utils/useOrganization';
  5. import usePageFilters from 'sentry/utils/usePageFilters';
  6. import PageOverview from 'sentry/views/performance/browser/webVitals/pageOverview';
  7. jest.mock('sentry/utils/useLocation');
  8. jest.mock('sentry/utils/usePageFilters');
  9. jest.mock('sentry/utils/useOrganization');
  10. describe('PageOverview', function () {
  11. const organization = OrganizationFixture({
  12. features: ['starfish-browser-webvitals', 'performance-database-view'],
  13. });
  14. let eventsMock;
  15. beforeEach(function () {
  16. jest.mocked(useLocation).mockReturnValue({
  17. pathname: '',
  18. search: '',
  19. query: {},
  20. hash: '',
  21. state: undefined,
  22. action: 'PUSH',
  23. key: '',
  24. });
  25. jest.mocked(usePageFilters).mockReturnValue({
  26. isReady: true,
  27. desyncedFilters: new Set(),
  28. pinnedFilters: new Set(),
  29. shouldPersist: true,
  30. selection: {
  31. datetime: {
  32. period: '10d',
  33. start: null,
  34. end: null,
  35. utc: false,
  36. },
  37. environments: [],
  38. projects: [],
  39. },
  40. });
  41. jest.mocked(useOrganization).mockReturnValue(organization);
  42. eventsMock = MockApiClient.addMockResponse({
  43. url: `/organizations/${organization.slug}/events/`,
  44. body: {
  45. data: [],
  46. },
  47. });
  48. MockApiClient.addMockResponse({
  49. url: `/organizations/${organization.slug}/events-stats/`,
  50. body: {},
  51. });
  52. MockApiClient.addMockResponse({
  53. url: `/organizations/${organization.slug}/spans-aggregation/`,
  54. body: {},
  55. });
  56. });
  57. afterEach(function () {
  58. jest.clearAllMocks();
  59. });
  60. it('renders FID deprecation alert', async () => {
  61. jest.mocked(useLocation).mockReturnValue({
  62. pathname: '',
  63. search: '',
  64. query: {useStoredScores: 'true', transaction: '/'},
  65. hash: '',
  66. state: undefined,
  67. action: 'PUSH',
  68. key: '',
  69. });
  70. render(<PageOverview />);
  71. await screen.findByText(/\(Interaction to Next Paint\) will replace/);
  72. await screen.findByText(
  73. /\(First Input Delay\) in our performance score calculation./
  74. );
  75. });
  76. it('renders interaction samples', async () => {
  77. const organizationWithInp = OrganizationFixture({
  78. features: [
  79. 'starfish-browser-webvitals',
  80. 'performance-database-view',
  81. 'starfish-browser-webvitals-replace-fid-with-inp',
  82. ],
  83. });
  84. jest.mocked(useOrganization).mockReturnValue(organizationWithInp);
  85. jest.mocked(useLocation).mockReturnValue({
  86. pathname: '',
  87. search: '',
  88. query: {useStoredScores: 'true', transaction: '/', type: 'interactions'},
  89. hash: '',
  90. state: undefined,
  91. action: 'PUSH',
  92. key: '',
  93. });
  94. render(<PageOverview />);
  95. await waitFor(() =>
  96. expect(eventsMock).toHaveBeenCalledWith(
  97. '/organizations/org-slug/events/',
  98. expect.objectContaining({
  99. query: expect.objectContaining({
  100. dataset: 'spansIndexed',
  101. field: [
  102. 'measurements.inp',
  103. 'measurements.score.inp',
  104. 'measurements.score.weight.inp',
  105. 'measurements.score.total',
  106. 'span_id',
  107. 'timestamp',
  108. 'profile_id',
  109. 'replay.id',
  110. 'user',
  111. 'origin.transaction',
  112. 'project',
  113. 'browser.name',
  114. 'span.self_time',
  115. 'span.description',
  116. ],
  117. query:
  118. 'span.op:ui.interaction.click measurements.score.weight.inp:>0 origin.transaction:/',
  119. }),
  120. })
  121. )
  122. );
  123. });
  124. it('escapes transaction name before querying discover', async () => {
  125. const organizationWithInp = OrganizationFixture({
  126. features: [
  127. 'starfish-browser-webvitals',
  128. 'performance-database-view',
  129. 'starfish-browser-webvitals-replace-fid-with-inp',
  130. ],
  131. });
  132. jest.mocked(useOrganization).mockReturnValue(organizationWithInp);
  133. jest.mocked(useLocation).mockReturnValue({
  134. pathname: '',
  135. search: '',
  136. query: {
  137. useStoredScores: 'true',
  138. transaction: '/page-with-a-*/',
  139. type: 'interactions',
  140. },
  141. hash: '',
  142. state: undefined,
  143. action: 'PUSH',
  144. key: '',
  145. });
  146. render(<PageOverview />);
  147. await waitFor(() =>
  148. expect(eventsMock).toHaveBeenCalledWith(
  149. '/organizations/org-slug/events/',
  150. expect.objectContaining({
  151. query: expect.objectContaining({
  152. dataset: 'spansIndexed',
  153. field: [
  154. 'measurements.inp',
  155. 'measurements.score.inp',
  156. 'measurements.score.weight.inp',
  157. 'measurements.score.total',
  158. 'span_id',
  159. 'timestamp',
  160. 'profile_id',
  161. 'replay.id',
  162. 'user',
  163. 'origin.transaction',
  164. 'project',
  165. 'browser.name',
  166. 'span.self_time',
  167. 'span.description',
  168. ],
  169. query:
  170. 'span.op:ui.interaction.click measurements.score.weight.inp:>0 origin.transaction:"/page-with-a-\\*/"',
  171. }),
  172. })
  173. )
  174. );
  175. });
  176. });