import {DashboardFixture} from 'sentry-fixture/dashboard'; import {RouterFixture} from 'sentry-fixture/routerFixture'; import {initializeOrg} from 'sentry-test/initializeOrg'; import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary'; import OrganizationStore from 'sentry/stores/organizationStore'; import PageFiltersStore from 'sentry/stores/pageFiltersStore'; import ProjectsStore from 'sentry/stores/projectsStore'; import WidgetBuilderV2 from 'sentry/views/dashboards/widgetBuilder/components/newWidgetBuilder'; const {organization, projects, router} = initializeOrg({ organization: {features: ['global-views', 'open-membership', 'dashboards-eap']}, projects: [ {id: '1', slug: 'project-1', isMember: true}, {id: '2', slug: 'project-2', isMember: true}, {id: '3', slug: 'project-3', isMember: false}, ], router: { location: { pathname: '/organizations/org-slug/dashboard/1/', query: {project: '-1'}, }, params: {}, }, }); describe('NewWidgetBuiler', function () { const onCloseMock = jest.fn(); const onSaveMock = jest.fn(); beforeEach(function () { OrganizationStore.init(); PageFiltersStore.init(); PageFiltersStore.onInitializeUrlState( { projects: [], environments: [], datetime: {start: null, end: null, period: '14d', utc: null}, }, new Set(['projects']) ); OrganizationStore.onUpdate(organization, {replace: true}); ProjectsStore.loadInitialData(projects); MockApiClient.addMockResponse({ url: '/organizations/org-slug/releases/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/dashboard/1/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/issues/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/events/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/events-stats/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/releases/stats/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/spans/fields/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/measurements-meta/', body: [], }); MockApiClient.addMockResponse({ url: '/organizations/org-slug/recent-searches/', }); }); afterEach(() => PageFiltersStore.reset()); it('renders', async function () { render( , { router, organization, } ); expect(await screen.findByText('Create Custom Widget')).toBeInTheDocument(); expect(await screen.findByLabelText('Close Widget Builder')).toBeInTheDocument(); expect(await screen.findByRole('button', {name: 'All Projects'})).toBeInTheDocument(); expect(await screen.findByRole('button', {name: 'All Envs'})).toBeInTheDocument(); expect(await screen.findByRole('button', {name: '14D'})).toBeInTheDocument(); expect(await screen.findByRole('button', {name: 'All Releases'})).toBeInTheDocument(); expect(await screen.findByPlaceholderText('Name')).toBeInTheDocument(); expect(await screen.findByText('+ Add Widget Description')).toBeInTheDocument(); expect(await screen.findByLabelText('Dataset')).toHaveAttribute('role', 'radiogroup'); expect(screen.getByText('Errors')).toBeInTheDocument(); expect(screen.getByText('Transactions')).toBeInTheDocument(); expect(screen.getByText('Spans')).toBeInTheDocument(); expect(screen.getByText('Issues')).toBeInTheDocument(); expect(screen.getByText('Releases')).toBeInTheDocument(); expect(screen.getByText('Table')).toBeInTheDocument(); // ensure the dropdown input has the default value 'table' expect(screen.getByDisplayValue('table')).toBeInTheDocument(); expect(screen.getByText('Filter')).toBeInTheDocument(); expect(screen.getByLabelText('Create a search query')).toBeInTheDocument(); // Test sort by selector for table display type expect(screen.getByText('Sort by')).toBeInTheDocument(); expect(screen.getByText('High to low')).toBeInTheDocument(); expect(screen.getByText(`Select a column\u{2026}`)).toBeInTheDocument(); expect(await screen.findByPlaceholderText('Name')).toBeInTheDocument(); expect(await screen.findByTestId('add-description')).toBeInTheDocument(); expect(screen.getByLabelText('Widget panel')).toBeInTheDocument(); await waitFor(() => { expect(screen.queryByText('Group by')).not.toBeInTheDocument(); }); }); it('render the filter alias field and add filter button on chart widgets', async function () { const chartsRouter = RouterFixture({ ...router, location: { ...router.location, query: {...router.location.query, displayType: 'line'}, }, }); render( , { router: chartsRouter, organization, } ); // see if alias field and add button are there expect(screen.getByPlaceholderText('Legend Alias')).toBeInTheDocument(); expect(screen.getByText('Add Filter')).toBeInTheDocument(); await waitFor(() => { expect(screen.queryByLabelText('Remove this filter')).not.toBeInTheDocument(); }); // add a field and see if delete buttons are there await userEvent.click(screen.getByText('Add Filter')); expect(screen.getAllByLabelText('Remove this filter')).toHaveLength(2); }); it('does not render the filter alias field and add filter button on other widgets', async function () { render( , { router, organization, } ); // see if alias field and add button are not there await waitFor(() => { expect(screen.queryByPlaceholderText('Legend Alias')).not.toBeInTheDocument(); }); expect(screen.queryByText('Add Filter')).not.toBeInTheDocument(); expect(screen.queryByLabelText('Remove this filter')).not.toBeInTheDocument(); }); it('renders the group by field on chart widgets', async function () { const chartsRouter = RouterFixture({ ...router, location: { ...router.location, query: {...router.location.query, displayType: 'line'}, }, }); render( , { router: chartsRouter, organization, } ); expect(await screen.findByText('Group by')).toBeInTheDocument(); expect(await screen.findByText('Select group')).toBeInTheDocument(); expect(await screen.findByText('Add Group')).toBeInTheDocument(); }); });