newWidgetBuilder.spec.tsx 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import {DashboardFixture} from 'sentry-fixture/dashboard';
  2. import {RouterFixture} from 'sentry-fixture/routerFixture';
  3. import {initializeOrg} from 'sentry-test/initializeOrg';
  4. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  5. import OrganizationStore from 'sentry/stores/organizationStore';
  6. import PageFiltersStore from 'sentry/stores/pageFiltersStore';
  7. import ProjectsStore from 'sentry/stores/projectsStore';
  8. import WidgetBuilderV2 from 'sentry/views/dashboards/widgetBuilder/components/newWidgetBuilder';
  9. const {organization, projects, router} = initializeOrg({
  10. organization: {features: ['global-views', 'open-membership', 'dashboards-eap']},
  11. projects: [
  12. {id: '1', slug: 'project-1', isMember: true},
  13. {id: '2', slug: 'project-2', isMember: true},
  14. {id: '3', slug: 'project-3', isMember: false},
  15. ],
  16. router: {
  17. location: {
  18. pathname: '/organizations/org-slug/dashboard/1/',
  19. query: {project: '-1'},
  20. },
  21. params: {},
  22. },
  23. });
  24. describe('NewWidgetBuiler', function () {
  25. const onCloseMock = jest.fn();
  26. const onSaveMock = jest.fn();
  27. beforeEach(function () {
  28. OrganizationStore.init();
  29. PageFiltersStore.init();
  30. PageFiltersStore.onInitializeUrlState(
  31. {
  32. projects: [],
  33. environments: [],
  34. datetime: {start: null, end: null, period: '14d', utc: null},
  35. },
  36. new Set(['projects'])
  37. );
  38. OrganizationStore.onUpdate(organization, {replace: true});
  39. ProjectsStore.loadInitialData(projects);
  40. MockApiClient.addMockResponse({
  41. url: '/organizations/org-slug/releases/',
  42. body: [],
  43. });
  44. MockApiClient.addMockResponse({
  45. url: '/organizations/org-slug/dashboard/1/',
  46. body: [],
  47. });
  48. MockApiClient.addMockResponse({
  49. url: '/organizations/org-slug/issues/',
  50. body: [],
  51. });
  52. MockApiClient.addMockResponse({
  53. url: '/organizations/org-slug/events/',
  54. body: [],
  55. });
  56. MockApiClient.addMockResponse({
  57. url: '/organizations/org-slug/events-stats/',
  58. body: [],
  59. });
  60. MockApiClient.addMockResponse({
  61. url: '/organizations/org-slug/releases/stats/',
  62. body: [],
  63. });
  64. MockApiClient.addMockResponse({
  65. url: '/organizations/org-slug/spans/fields/',
  66. body: [],
  67. });
  68. MockApiClient.addMockResponse({
  69. url: '/organizations/org-slug/measurements-meta/',
  70. body: [],
  71. });
  72. MockApiClient.addMockResponse({
  73. url: '/organizations/org-slug/recent-searches/',
  74. });
  75. });
  76. afterEach(() => PageFiltersStore.reset());
  77. it('renders', async function () {
  78. render(
  79. <WidgetBuilderV2
  80. isOpen
  81. onClose={onCloseMock}
  82. dashboard={DashboardFixture([])}
  83. dashboardFilters={{}}
  84. onSave={onSaveMock}
  85. />,
  86. {
  87. router,
  88. organization,
  89. }
  90. );
  91. expect(await screen.findByText('Create Custom Widget')).toBeInTheDocument();
  92. expect(await screen.findByLabelText('Close Widget Builder')).toBeInTheDocument();
  93. expect(await screen.findByRole('button', {name: 'All Projects'})).toBeInTheDocument();
  94. expect(await screen.findByRole('button', {name: 'All Envs'})).toBeInTheDocument();
  95. expect(await screen.findByRole('button', {name: '14D'})).toBeInTheDocument();
  96. expect(await screen.findByRole('button', {name: 'All Releases'})).toBeInTheDocument();
  97. expect(await screen.findByPlaceholderText('Name')).toBeInTheDocument();
  98. expect(await screen.findByText('+ Add Widget Description')).toBeInTheDocument();
  99. expect(await screen.findByLabelText('Dataset')).toHaveAttribute('role', 'radiogroup');
  100. expect(screen.getByText('Errors')).toBeInTheDocument();
  101. expect(screen.getByText('Transactions')).toBeInTheDocument();
  102. expect(screen.getByText('Spans')).toBeInTheDocument();
  103. expect(screen.getByText('Issues')).toBeInTheDocument();
  104. expect(screen.getByText('Releases')).toBeInTheDocument();
  105. expect(screen.getByText('Table')).toBeInTheDocument();
  106. // ensure the dropdown input has the default value 'table'
  107. expect(screen.getByDisplayValue('table')).toBeInTheDocument();
  108. expect(screen.getByText('Filter')).toBeInTheDocument();
  109. expect(screen.getByLabelText('Create a search query')).toBeInTheDocument();
  110. // Test sort by selector for table display type
  111. expect(screen.getByText('Sort by')).toBeInTheDocument();
  112. expect(screen.getByText('High to low')).toBeInTheDocument();
  113. expect(screen.getByText(`Select a column\u{2026}`)).toBeInTheDocument();
  114. expect(await screen.findByPlaceholderText('Name')).toBeInTheDocument();
  115. expect(await screen.findByTestId('add-description')).toBeInTheDocument();
  116. expect(screen.getByLabelText('Widget panel')).toBeInTheDocument();
  117. await waitFor(() => {
  118. expect(screen.queryByText('Group by')).not.toBeInTheDocument();
  119. });
  120. });
  121. it('render the filter alias field and add filter button on chart widgets', async function () {
  122. const chartsRouter = RouterFixture({
  123. ...router,
  124. location: {
  125. ...router.location,
  126. query: {...router.location.query, displayType: 'line'},
  127. },
  128. });
  129. render(
  130. <WidgetBuilderV2
  131. isOpen
  132. onClose={onCloseMock}
  133. dashboard={DashboardFixture([])}
  134. dashboardFilters={{}}
  135. onSave={onSaveMock}
  136. />,
  137. {
  138. router: chartsRouter,
  139. organization,
  140. }
  141. );
  142. // see if alias field and add button are there
  143. expect(screen.getByPlaceholderText('Legend Alias')).toBeInTheDocument();
  144. expect(screen.getByText('Add Filter')).toBeInTheDocument();
  145. await waitFor(() => {
  146. expect(screen.queryByLabelText('Remove this filter')).not.toBeInTheDocument();
  147. });
  148. // add a field and see if delete buttons are there
  149. await userEvent.click(screen.getByText('Add Filter'));
  150. expect(screen.getAllByLabelText('Remove this filter')).toHaveLength(2);
  151. });
  152. it('does not render the filter alias field and add filter button on other widgets', async function () {
  153. render(
  154. <WidgetBuilderV2
  155. isOpen
  156. onClose={onCloseMock}
  157. dashboard={DashboardFixture([])}
  158. dashboardFilters={{}}
  159. onSave={onSaveMock}
  160. />,
  161. {
  162. router,
  163. organization,
  164. }
  165. );
  166. // see if alias field and add button are not there
  167. await waitFor(() => {
  168. expect(screen.queryByPlaceholderText('Legend Alias')).not.toBeInTheDocument();
  169. });
  170. expect(screen.queryByText('Add Filter')).not.toBeInTheDocument();
  171. expect(screen.queryByLabelText('Remove this filter')).not.toBeInTheDocument();
  172. });
  173. it('renders the group by field on chart widgets', async function () {
  174. const chartsRouter = RouterFixture({
  175. ...router,
  176. location: {
  177. ...router.location,
  178. query: {...router.location.query, displayType: 'line'},
  179. },
  180. });
  181. render(
  182. <WidgetBuilderV2
  183. isOpen
  184. onClose={onCloseMock}
  185. dashboard={DashboardFixture([])}
  186. dashboardFilters={{}}
  187. onSave={onSaveMock}
  188. />,
  189. {
  190. router: chartsRouter,
  191. organization,
  192. }
  193. );
  194. expect(await screen.findByText('Group by')).toBeInTheDocument();
  195. expect(await screen.findByText('Select group')).toBeInTheDocument();
  196. expect(await screen.findByText('Add Group')).toBeInTheDocument();
  197. });
  198. });