@testing-library/react#getByRole TypeScript Examples

The following examples show how to use @testing-library/react#getByRole. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ExperimentForm.test.tsx    From abacus with GNU General Public License v2.0 6 votes vote down vote up
test('skipping to submit should check all sections', async () => {
  MockDate.set('2020-08-13')

  const onSubmit = async () => undefined

  const { container } = render(
    <ExperimentForm
      indexedMetrics={Normalizers.indexMetrics(Fixtures.createMetrics(20))}
      indexedSegments={Normalizers.indexSegments(Fixtures.createSegments(20))}
      initialExperiment={experimentToFormData({})}
      onSubmit={onSubmit}
      completionBag={completionBag}
    />,
  )

  const startSectionButton = screen.getByRole('button', { name: /Start/ })
  const basicInfoSectionButton = screen.getByRole('button', { name: /Basic Info/ })
  const audienceSectionButton = screen.getByRole('button', { name: /Audience/ })
  const metricsSectionButton = screen.getByRole('button', { name: /Metrics/ })
  const submitSectionButton = screen.getByRole('button', { name: /Submit/ })

  await act(async () => {
    fireEvent.click(submitSectionButton)
  })

  expect(container).toMatchSnapshot()

  expect(isSectionError(startSectionButton)).toBe(true)
  expect(isSectionError(basicInfoSectionButton)).toBe(true)
  expect(isSectionError(audienceSectionButton)).toBe(true)
  expect(isSectionError(metricsSectionButton)).toBe(true)
  expect(isSectionError(submitSectionButton)).toBe(false)

  expect(isSectionComplete(startSectionButton)).toBe(false)
  expect(isSectionComplete(basicInfoSectionButton)).toBe(false)
  expect(isSectionComplete(audienceSectionButton)).toBe(false)
  expect(isSectionComplete(metricsSectionButton)).toBe(false)
  expect(isSectionComplete(submitSectionButton)).toBe(false)
})
Example #2
Source File: ProjectSelect.test.tsx    From backstage with Apache License 2.0 6 votes vote down vote up
describe('<ProjectSelect />', () => {
  let Component: React.ReactNode;
  beforeEach(() => {
    Component = () => (
      <MockFilterProvider>
        <ProjectSelect
          project="all"
          projects={mockProjects}
          onSelect={jest.fn()}
        />
      </MockFilterProvider>
    );
  });

  it('Renders without exploding', async () => {
    const rendered = await renderInTestApp(Component);
    expect(rendered.getByText('All Projects')).toBeInTheDocument();
  });

  it('shows all projects in the filter select', async () => {
    const rendered = await renderInTestApp(Component);
    const projectSelectContainer = rendered.getByTestId(
      'project-filter-select',
    );
    const button = getByRole(projectSelectContainer, 'button');
    await userEvent.click(button);
    await waitFor(() => rendered.getByTestId('option-all'));

    mockProjects.forEach(project =>
      expect(
        rendered.getByText(project.name ?? project.id),
      ).toBeInTheDocument(),
    );
  });
});
Example #3
Source File: index.test.tsx    From firebase-tools-ui with Apache License 2.0 6 votes vote down vote up
it('links to the hosting website externally', () => {
  const { getByTestId } = render(
    <MemoryRouter>
      <TestEmulatorConfigProvider
        config={{
          projectId: 'example',
          hosting: {
            host: 'localhost',
            port: 5000,
            hostAndPort: 'localhost:5000',
          },
        }}
      >
        <Home></Home>
      </TestEmulatorConfigProvider>
    </MemoryRouter>
  );

  const card = getByTestId(`emulator-info-hosting`);
  expect(getByText(card, '5000')).not.toBeNull();
  const link = getByRole(card, 'link', {
    name: 'View website',
  }) as HTMLAnchorElement;
  expect(link.href).toBe('http://localhost:5000/');
  expect(link.target).toBe('_blank');
});
Example #4
Source File: MetricAssignmentsPanel.test.tsx    From abacus with GNU General Public License v2.0 5 votes vote down vote up
test('opens, submits and cancels assign metric dialog', async () => {
  const metrics = Fixtures.createMetrics(5)
  const experiment = Fixtures.createExperimentFull({ status: Status.Running })
  const experimentReloadRef: React.MutableRefObject<() => void> = { current: noop }
  render(<MetricAssignmentsPanel {...{ experiment, metrics, experimentReloadRef }} />)

  mockedExperimentsApi.assignMetric.mockReset()
  // @ts-ignore
  mockedExperimentsApi.assignMetric.mockImplementationOnce(async () => null)

  const startAssignButton = screen.getByRole('button', { name: /Assign Metric/ })
  fireEvent.click(startAssignButton)

  await waitFor(() => screen.getByRole('button', { name: 'Assign' }))
  const assignButton = screen.getByRole('button', { name: 'Assign' })

  // We click it now to test the validation state
  fireEvent.click(assignButton)

  const metricSearchField = screen.getByRole('combobox', { name: /Select a metric/ })
  const metricSearchFieldMoreButton = getByRole(metricSearchField, 'button', { name: 'Open' })
  fireEvent.click(metricSearchFieldMoreButton)
  fireEvent.click(await screen.findByRole('option', { name: /metric_3/ }))

  const attributionWindowField = await screen.findByLabelText(/Attribution Window/)
  await act(async () => {
    fireEvent.focus(attributionWindowField)
  })
  await act(async () => {
    fireEvent.keyDown(attributionWindowField, { key: 'Enter' })
  })
  const attributionWindowFieldOption = await screen.findByRole('option', { name: /24 hours/ })
  await act(async () => {
    fireEvent.click(attributionWindowFieldOption)
  })

  await changeFieldByRole('spinbutton', /Minimum Difference/, '1')

  fireEvent.click(assignButton)
  await waitForElementToBeRemoved(assignButton)

  expect(mockedExperimentsApi.assignMetric).toHaveBeenCalledTimes(1)
  expect(mockedExperimentsApi.assignMetric).toHaveBeenLastCalledWith(experiment, {
    attributionWindowSeconds: '86400',
    changeExpected: false,
    isPrimary: false,
    metricId: 3,
    minDifference: '0.01',
  })

  fireEvent.click(startAssignButton)

  await waitFor(() => screen.getByRole('button', { name: /Cancel/ }))

  const cancelButton = screen.getByRole('button', { name: /Cancel/ })
  fireEvent.click(cancelButton)
  await waitForElementToBeRemoved(cancelButton)

  expect(mockedExperimentsApi.assignMetric).toHaveBeenCalledTimes(1)
})
Example #5
Source File: ExperimentForm.test.tsx    From abacus with GNU General Public License v2.0 5 votes vote down vote up
test('sections should be browsable by the next and prev buttons', async () => {
  MockDate.set('2020-08-13')

  const onSubmit = async () => undefined

  render(
    <ExperimentForm
      indexedMetrics={Normalizers.indexMetrics(Fixtures.createMetrics(20))}
      indexedSegments={Normalizers.indexSegments(Fixtures.createSegments(20))}
      initialExperiment={experimentToFormData({})}
      onSubmit={onSubmit}
      completionBag={completionBag}
    />,
  )

  screen.getByText(/Design and Document Your Experiment/)
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Begin/ }))
  })
  screen.getAllByText(/Basic Info/)
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Previous/ }))
  })
  screen.getByText(/Design and Document Your Experiment/)
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Begin/ }))
  })
  screen.getAllByText(/Basic Info/)
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })
  screen.getByText(/Define Your Audience/)
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })
  screen.getByText(/Assign Metrics/)
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })
  screen.getByText(/Confirm and Submit Your Experiment/)
})
Example #6
Source File: ExperimentForm.test.tsx    From abacus with GNU General Public License v2.0 5 votes vote down vote up
test('sections should be browsable by the section buttons and show validation errors without crashing', async () => {
  MockDate.set('2020-08-13')

  const onSubmit = async () => undefined

  const { container } = render(
    <ExperimentForm
      indexedMetrics={Normalizers.indexMetrics(Fixtures.createMetrics(20))}
      indexedSegments={Normalizers.indexSegments(Fixtures.createSegments(20))}
      initialExperiment={experimentToFormData({})}
      onSubmit={onSubmit}
      completionBag={completionBag}
    />,
  )

  const basicInfoSectionButton = screen.getByRole('button', { name: /Basic Info/ })
  const audienceSectionButton = screen.getByRole('button', { name: /Audience/ })
  const metricsSectionButton = screen.getByRole('button', { name: /Metrics/ })
  const submitSectionButton = screen.getByRole('button', { name: /Submit/ })

  // The order of these is such that it triggers all validation error paths

  screen.getByText(/Design and Document Your Experiment/)
  expect(container).toMatchSnapshot()

  await act(async () => {
    fireEvent.click(submitSectionButton)
  })

  screen.getByText(/Confirm and Submit Your Experiment/)
  expect(container).toMatchSnapshot()

  await act(async () => {
    fireEvent.click(metricsSectionButton)
  })

  // We add a metricAssignment first so it can show validation errors
  screen.getByText(/Assign Metrics/)
  expect(container).toMatchSnapshot()
  const metricSearchField = screen.getByRole('combobox', { name: /Select a metric/ })
  const metricSearchFieldMoreButton = getByRole(metricSearchField, 'button', { name: 'Open' })
  const metricAddButton = screen.getByRole('button', { name: 'Add metric' })

  fireEvent.click(metricSearchFieldMoreButton)
  const metricOption = await screen.findByRole('option', { name: /metric_10/ })
  await act(async () => {
    fireEvent.click(metricOption)
  })
  await act(async () => {
    fireEvent.click(metricAddButton)
  })

  await act(async () => {
    fireEvent.click(basicInfoSectionButton)
  })

  screen.getAllByText(/Basic Info/)
  expect(container).toMatchSnapshot()

  await act(async () => {
    fireEvent.click(metricsSectionButton)
  })

  screen.getByText(/Assign Metrics/)
  expect(container).toMatchSnapshot()

  await act(async () => {
    fireEvent.click(audienceSectionButton)
  })

  screen.getByText(/Define Your Audience/)
  expect(container).toMatchSnapshot()

  // Activating the variations level validation error:
  const allocatedPercentage = screen.getAllByRole('spinbutton', { name: /Allocated percentage/i })
  await act(async () => {
    fireEvent.change(allocatedPercentage[0], { target: { value: '99' } })
  })
  fireEvent.blur(allocatedPercentage[0])
})
Example #7
Source File: ExperimentForm.test.tsx    From abacus with GNU General Public License v2.0 5 votes vote down vote up
test('section should be validated after change', async () => {
  MockDate.set('2020-08-13')

  const onSubmit = async () => undefined

  render(
    <ExperimentForm
      indexedMetrics={Normalizers.indexMetrics(Fixtures.createMetrics(20))}
      indexedSegments={Normalizers.indexSegments(Fixtures.createSegments(20))}
      initialExperiment={experimentToFormData({})}
      onSubmit={onSubmit}
      completionBag={completionBag}
    />,
  )

  const startSectionButton = screen.getByRole('button', { name: /Start/ })
  const basicInfoSectionButton = screen.getByRole('button', { name: /Basic Info/ })
  const audienceSectionButton = screen.getByRole('button', { name: /Audience/ })
  const metricsSectionButton = screen.getByRole('button', { name: /Metrics/ })
  const submitSectionButton = screen.getByRole('button', { name: /Submit/ })

  expect(isSectionError(startSectionButton)).toBe(false)
  expect(isSectionError(basicInfoSectionButton)).toBe(false)
  expect(isSectionError(audienceSectionButton)).toBe(false)
  expect(isSectionError(metricsSectionButton)).toBe(false)
  expect(isSectionError(submitSectionButton)).toBe(false)

  expect(isSectionComplete(startSectionButton)).toBe(false)
  expect(isSectionComplete(basicInfoSectionButton)).toBe(false)
  expect(isSectionComplete(audienceSectionButton)).toBe(false)
  expect(isSectionComplete(metricsSectionButton)).toBe(false)
  expect(isSectionComplete(submitSectionButton)).toBe(false)

  await act(async () => {
    fireEvent.click(basicInfoSectionButton)
  })

  screen.getByRole('textbox', { name: /Experiment name/ })

  expect(isSectionError(startSectionButton)).toBe(true)
  expect(isSectionError(basicInfoSectionButton)).toBe(false)
  expect(isSectionError(audienceSectionButton)).toBe(false)
  expect(isSectionError(metricsSectionButton)).toBe(false)
  expect(isSectionError(submitSectionButton)).toBe(false)

  expect(isSectionComplete(startSectionButton)).toBe(false)
  expect(isSectionComplete(basicInfoSectionButton)).toBe(false)
  expect(isSectionComplete(audienceSectionButton)).toBe(false)
  expect(isSectionComplete(metricsSectionButton)).toBe(false)
  expect(isSectionComplete(submitSectionButton)).toBe(false)

  await act(async () => {
    fireEvent.click(startSectionButton)
  })

  const postUrlInput = screen.getByRole('textbox', { name: /Your Post's URL/ })

  await act(async () => {
    fireEvent.change(postUrlInput, { target: { value: 'http://example.com/' } })
  })

  await act(async () => {
    fireEvent.click(basicInfoSectionButton)
  })

  expect(isSectionError(startSectionButton)).toBe(false)
  expect(isSectionError(basicInfoSectionButton)).toBe(false)
  expect(isSectionError(audienceSectionButton)).toBe(false)
  expect(isSectionError(metricsSectionButton)).toBe(false)
  expect(isSectionError(submitSectionButton)).toBe(false)

  expect(isSectionComplete(startSectionButton)).toBe(true)
  expect(isSectionComplete(basicInfoSectionButton)).toBe(false)
  expect(isSectionComplete(audienceSectionButton)).toBe(false)
  expect(isSectionComplete(metricsSectionButton)).toBe(false)
  expect(isSectionComplete(submitSectionButton)).toBe(false)
})
Example #8
Source File: Metrics.test.tsx    From abacus with GNU General Public License v2.0 5 votes vote down vote up
test('allows adding, editing and removing a Metric Assignment', async () => {
  const { container } = render(
    <Formik
      initialValues={{ experiment: experimentToFormData({}) }}
      onSubmit={
        /* istanbul ignore next; This is unused */
        () => undefined
      }
    >
      {(formikProps) => <Metrics {...{ indexedMetrics, completionBag, formikProps }} />}
    </Formik>,
  )
  expect(container).toMatchSnapshot()

  const metricSearchField = screen.getByRole('combobox', { name: /Select a metric/ })
  const metricSearchFieldMoreButton = getByRole(metricSearchField, 'button', { name: 'Open' })
  const metricAddButton = screen.getByRole('button', { name: 'Add metric' })

  fireEvent.click(metricAddButton)

  expect(container).toMatchSnapshot()

  fireEvent.click(metricSearchFieldMoreButton)
  fireEvent.click(await screen.findByRole('option', { name: /asdf_7d_refund/ }))
  fireEvent.click(metricAddButton)

  expect(container).toMatchSnapshot()

  const changeExpectedSwitch = screen.getByLabelText(/Change Expected/)

  // eslint-disable-next-line @typescript-eslint/require-await
  await act(async () => {
    fireEvent.click(changeExpectedSwitch)
  })

  await changeFieldByRole('spinbutton', /Minimum Difference/, '0.01')

  const moreMenu = screen.getByRole('button', { name: /more/ })
  fireEvent.click(moreMenu)

  expect(container).toMatchSnapshot()

  const setAsPrimary = screen.getByRole('menuitem', { name: /Set as Primary/ })
  // eslint-disable-next-line @typescript-eslint/require-await
  await act(async () => {
    fireEvent.click(setAsPrimary)
  })

  expect(container).toMatchSnapshot()

  fireEvent.click(moreMenu)
  const remove = screen.getByRole('menuitem', { name: /Remove/ })
  // eslint-disable-next-line @typescript-eslint/require-await
  await act(async () => {
    fireEvent.click(remove)
  })

  expect(container).toMatchSnapshot()

  fireEvent.click(metricSearchFieldMoreButton)
  fireEvent.click(await screen.findByRole('option', { name: /registration_start/ }))
  // eslint-disable-next-line @typescript-eslint/require-await
  await act(async () => {
    fireEvent.click(metricAddButton)
  })

  expect(container).toMatchSnapshot()
})
Example #9
Source File: PeriodSelect.test.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
describe('<PeriodSelect />', () => {
  it('Renders without exploding', async () => {
    const rendered = await renderInTestApp(
      <MockBillingDateProvider
        lastCompleteBillingDate={lastCompleteBillingDate}
      >
        <PeriodSelect
          duration={DefaultPageFilters.duration}
          onSelect={jest.fn()}
        />
      </MockBillingDateProvider>,
    );
    expect(rendered.getByTestId('period-select')).toBeInTheDocument();
  });

  it('Should display all costGrowth period options', async () => {
    const rendered = await renderInTestApp(
      <MockBillingDateProvider
        lastCompleteBillingDate={lastCompleteBillingDate}
      >
        <PeriodSelect
          duration={DefaultPageFilters.duration}
          onSelect={jest.fn()}
        />
      </MockBillingDateProvider>,
    );
    const periodSelectContainer = rendered.getByTestId('period-select');
    const button = getByRole(periodSelectContainer, 'button');
    await userEvent.click(button);
    await waitFor(() => rendered.getByText('Past 60 Days'));
    options.forEach(option =>
      expect(
        rendered.getByTestId(`period-select-option-${option.value}`),
      ).toBeInTheDocument(),
    );
  });

  describe.each`
    duration
    ${Duration.P3M}
    ${Duration.P90D}
    ${Duration.P30D}
  `('Should select the correct duration', ({ duration }) => {
    it(`Should select ${duration}`, async () => {
      const mockOnSelect = jest.fn();
      const mockAggregation =
        // Can't select an option that's already the default
        DefaultPageFilters.duration === duration
          ? Duration.P30D
          : DefaultPageFilters.duration;

      const rendered = await renderInTestApp(
        <MockBillingDateProvider
          lastCompleteBillingDate={lastCompleteBillingDate}
        >
          <PeriodSelect duration={mockAggregation} onSelect={mockOnSelect} />,
        </MockBillingDateProvider>,
      );
      const periodSelect = rendered.getByTestId('period-select');
      const button = getByRole(periodSelect, 'button');

      await userEvent.click(button);
      await userEvent.click(
        rendered.getByTestId(`period-select-option-${duration}`),
      );
      expect(mockOnSelect).toHaveBeenLastCalledWith(duration);
    });
  });
});
Example #10
Source File: ExperimentForm.test.tsx    From abacus with GNU General Public License v2.0 4 votes vote down vote up
test('form submits with valid fields', async () => {
  MockDate.set('2020-08-13')

  let submittedData: unknown = null
  const onSubmit = async (formData: unknown): Promise<undefined> => {
    // We need to add a timeout here so the loading indicator renders
    await new Promise((resolve) => setTimeout(resolve, StatusCodes.OK))
    submittedData = formData
    return
  }

  render(
    <ExperimentForm
      indexedMetrics={Normalizers.indexMetrics(Fixtures.createMetrics(20))}
      indexedSegments={Normalizers.indexSegments(Fixtures.createSegments(20))}
      initialExperiment={experimentToFormData({})}
      onSubmit={onSubmit}
      completionBag={completionBag}
    />,
  )

  // ### Start
  screen.getByText(/Design and Document Your Experiment/)
  await changeFieldByRole('textbox', /Your Post's URL/, 'http://example.com/')
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Begin/ }))
  })

  // ### Basic Info
  screen.getAllByText(/Basic Info/)
  await changeFieldByRole('textbox', /Experiment name/, 'test_experiment_name')
  await changeFieldByRole('textbox', /Experiment description/, 'experiment description')
  // We need to make some dates relative to today since mocking the schema to work with MockDate is a pain!
  const now = new Date()
  now.setDate(now.getDate() + 1)
  const nextWeek = new Date()
  nextWeek.setDate(now.getDate() + 7)
  await act(async () => {
    fireEvent.change(screen.getByLabelText(/Start date/), { target: { value: formatIsoDate(now) } })
  })
  await act(async () => {
    fireEvent.change(screen.getByLabelText(/End date/), { target: { value: formatIsoDate(nextWeek) } })
  })
  // search for the user
  await act(async () => {
    await changeFieldByRole('textbox', /Owner/, 'testing')
  })
  // click the selected user
  await act(async () => {
    fireEvent.click(screen.getByText('testing (owner-nickname)'))
  })
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })

  // ### Audience
  screen.getByText(/Define Your Audience/)

  const platformField = screen.getByRole('button', { name: /Select a Platform/ })
  await act(async () => {
    fireEvent.focus(platformField)
  })
  await act(async () => {
    fireEvent.keyDown(platformField, { key: 'Enter' })
  })
  const platformOption = await screen.findByRole('option', { name: /wpcom/ })
  await act(async () => {
    fireEvent.click(platformOption)
  })

  const targetingField = screen.getByRole('textbox', { name: /Targeting/ })
  fireEvent.change(targetingField, { target: { value: 'segment_3' } })
  const targetingOption = await screen.findByRole('option', { name: /Locale: segment_3/ })
  await act(async () => {
    fireEvent.click(targetingOption)
  })

  const addVariationButton = screen.getByRole('button', { name: /Add variation/i })
  fireEvent.click(addVariationButton)

  const variationNames = screen.getAllByRole('textbox', { name: /Variation name/i })
  fireEvent.change(variationNames[1], { target: { value: 'treatment_2' } })

  const allocatedPercentages = screen.getAllByRole('spinbutton', { name: /Allocated percentage/i })
  await act(async () => {
    fireEvent.change(allocatedPercentages[0], { target: { value: '33' } })
    fireEvent.change(allocatedPercentages[1], { target: { value: '33' } })
    fireEvent.change(allocatedPercentages[2], { target: { value: '33' } })
  })

  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })

  // ### Metrics
  screen.getByText(/Assign Metrics/)
  const metricSearchField = screen.getByRole('combobox', { name: /Select a metric/ })
  const metricSearchFieldMoreButton = getByRole(metricSearchField, 'button', { name: 'Open' })
  const metricAddButton = screen.getByRole('button', { name: 'Add metric' })

  fireEvent.click(metricSearchFieldMoreButton)
  const metricOption = await screen.findByRole('option', { name: /metric_10/ })
  await act(async () => {
    fireEvent.click(metricOption)
  })
  await act(async () => {
    fireEvent.click(metricAddButton)
  })

  const attributionWindowField = await screen.findByLabelText('Attribution Window')
  await act(async () => {
    fireEvent.focus(attributionWindowField)
  })
  await act(async () => {
    fireEvent.keyDown(attributionWindowField, { key: 'Enter' })
  })
  const attributionWindowFieldOption = await screen.findByRole('option', { name: /24 hours/ })
  await act(async () => {
    fireEvent.click(attributionWindowFieldOption)
  })

  await changeFieldByRole('spinbutton', /Minimum Difference/, '0.01')

  // #### Exposure Events
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Add exposure event/ }))
  })
  await act(async () => {
    fireEvent.click(await screen.findByRole('button', { name: /Add Property/ }))
  })
  await act(async () => {
    fireEvent.click(await screen.findByRole('button', { name: /Remove exposure event property/ }))
  })
  await act(async () => {
    fireEvent.click(await screen.findByRole('button', { name: /Remove exposure event/ }))
  })
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Add exposure event/ }))
  })
  await act(async () => {
    fireEvent.click(await screen.findByRole('button', { name: /Add Property/ }))
  })
  // search for the event
  await act(async () => {
    await changeFieldByRole('textbox', /Event Name/, 'event_name')
  })
  // click the selected event
  await act(async () => {
    fireEvent.click(screen.getByText('event_name'))
  })
  // enter the prop value
  await act(async () => {
    await changeFieldByRole('textbox', /Key/, 'prop_key_value')
  })
  await changeFieldByRole('textbox', /Property Value/, 'value')

  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })

  // ### Submit
  screen.getByText(/Confirm and Submit Your Experiment/)
  await act(async () => {
    screen.getAllByRole('button', { name: /Submit/ })
    const submit = screen
      .getAllByRole('button', { name: /Submit/ })
      .find((submit) => submit.getAttribute('type') === 'submit')
    if (!submit) {
      throw new Error(`Can't find submit button.`)
    }
    fireEvent.click(submit)
  })

  await waitFor(() => expect(submittedData).not.toBeNull())

  expect(submittedData).toEqual({
    experiment: {
      p2Url: 'http://example.com/',
      name: 'test_experiment_name',
      description: 'experiment description',
      startDatetime: formatIsoDate(now),
      endDatetime: formatIsoDate(nextWeek),
      exclusionGroupTagIds: [],
      ownerLogin: 'owner-nickname',
      platform: 'wpcom',
      existingUsersAllowed: 'true',
      exposureEvents: [
        {
          event: 'event_name',
          props: [
            {
              key: 'prop_key_value',
              value: 'value',
            },
          ],
        },
      ],
      segmentAssignments: [
        {
          isExcluded: false,
          segmentId: 3,
        },
      ],
      variations: [
        {
          allocatedPercentage: 33,
          isDefault: true,
          name: 'control',
        },
        {
          allocatedPercentage: 33,
          isDefault: false,
          name: 'treatment',
        },
        {
          allocatedPercentage: 33,
          isDefault: false,
          name: 'treatment_2',
        },
      ],
      metricAssignments: [
        {
          attributionWindowSeconds: '86400',
          changeExpected: true,
          isPrimary: true,
          metricId: 10,
          minDifference: 0.01,
        },
      ],
    },
  })
})
Example #11
Source File: ExperimentForm.test.tsx    From abacus with GNU General Public License v2.0 4 votes vote down vote up
test('form submits an edited experiment without any changes', async () => {
  MockDate.set('2020-08-13')

  const experiment = Fixtures.createExperimentFull({
    status: Status.Staging,
    conclusionUrl: undefined,
    deployedVariationId: undefined,
    endReason: undefined,
  })

  let submittedData: unknown = null
  const onSubmit = async (formData: unknown): Promise<undefined> => {
    // We need to add a timeout here so the loading indicator renders
    await new Promise((resolve) => setTimeout(resolve, StatusCodes.OK))
    submittedData = formData
    return
  }

  render(
    <ExperimentForm
      indexedMetrics={Normalizers.indexMetrics(Fixtures.createMetrics(20))}
      indexedSegments={Normalizers.indexSegments(Fixtures.createSegments(20))}
      initialExperiment={experimentToFormData(experiment)}
      onSubmit={onSubmit}
      completionBag={completionBag}
    />,
  )

  // ### Move through the form stages
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Begin/ }))
  })
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })
  await act(async () => {
    fireEvent.click(screen.getByRole('button', { name: /Next/ }))
  })

  // ### Submit
  screen.getByText(/Confirm and Submit Your Experiment/)

  const submit = screen
    .getAllByRole('button', { name: /Submit/ })
    .find((submit) => submit.getAttribute('type') === 'submit')
  if (!submit) {
    throw new Error(`Can't find submit button.`)
  }
  fireEvent.click(submit)

  await waitFor(() => expect(submittedData).not.toBeNull())

  const validatedExperiment = await validationErrorDisplayer(
    experimentFullNewSchema.validate((submittedData as { experiment: unknown }).experiment),
  )

  // We need to remove Ids, status, conclusion data, reformat exposure events to make it like new
  const newShapedExperiment = _.omit(
    _.clone(experiment),
    'experimentId',
    'status',
    'assignmentCacheStatus',
    'conclusionUrl',
    'deployedVariationId',
    'endReason',
  )
  // @ts-ignore
  newShapedExperiment.metricAssignments.forEach((metricAssignment) => delete metricAssignment.metricAssignmentId)
  // @ts-ignore
  newShapedExperiment.segmentAssignments.forEach((segmentAssignment) => delete segmentAssignment.segmentAssignmentId)
  // @ts-ignore
  newShapedExperiment.variations.forEach((variation) => delete variation.variationId)
  newShapedExperiment.exposureEvents?.forEach((exposureEvent) => {
    exposureEvent.props = _.toPairs(exposureEvent.props || {}).map(([key, value]) => ({ key, value }))
  })

  expect(validatedExperiment).toEqual(newShapedExperiment)
})