@testing-library/dom#fireEvent TypeScript Examples

The following examples show how to use @testing-library/dom#fireEvent. 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: Select.test.tsx    From chroma-react with MIT License 6 votes vote down vote up
test('it sets the default checked state on options', async () => {
  const props = getBaseProps();
  const { findByTestId } = renderWithTheme(
    <Select {...props} value="option2" data-testid={testId}>
      <SelectOption title="option1" value="option1" />
      <SelectOption title="option2" value="option2" data-testid={optionId} />
      <SelectOption title="option3" value="option3" />
    </Select>
  );

  const select = await findByTestId(testId);

  fireEvent.click(select);
  const checkedOption = await findByTestId(optionId);
  const visuallyHiddenCheck = await within(checkedOption).findByText('✓');
  expect(visuallyHiddenCheck).toBeInTheDocument();
});
Example #2
Source File: ChatMessages.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 6 votes vote down vote up
// test('cancel after dialog box open', async () => {
//   const { getByText, getByTestId } = render(chatMessages);
//   await waitFor(() => {
//     fireEvent.click(getByTestId('messageOptions'));
//     fireEvent.click(getByTestId('dialogButton'));
//   });

//   fireEvent.click(getByText('Cancel'));
// });

// Need to first scroll up

test('click on Jump to latest', async () => {
  const { getByTestId } = render(chatMessages);
  const messageContainer: any = document.querySelector('.messageContainer');

  await act(async () => {
    await new Promise((r) => setTimeout(r, 1500));
  });

  fireEvent.scroll(messageContainer, { target: { scrollTop: 10 } });

  await waitFor(() => {
    fireEvent.click(getByTestId('jumpToLatest'));
  });
});
Example #3
Source File: Select.test.tsx    From chroma-react with MIT License 6 votes vote down vote up
test('it can be operated using only the keyboard', async () => {
  const props = getBaseProps();
  const mockFn = jest.fn();

  const { findByTestId, findAllByRole } = renderWithTheme(
    <Select {...props} onChange={mockFn} data-testid={testId}>
      <SelectOption title="option1" value="option1" />
      <SelectOption title="option2" value="option2" />
    </Select>
  );

  const select = await findByTestId(testId);

  fireEvent.click(select);

  const [option1, option2] = await findAllByRole('option');

  // First option should always have focus
  expect(option1).toHaveFocus();
  // Arrow down should focus next item
  press.ArrowDown();
  expect(option2).toHaveFocus();
  // Arrow up should focus previous item
  press.ArrowUp();
  expect(option1).toHaveFocus();
  // Change back to option 2
  press.ArrowDown();
  // Enter should "submit" the select
  press.Enter();
  expect(mockFn).toHaveBeenCalledTimes(1);
  expect(mockFn).toHaveBeenCalledWith('option2', undefined);
});
Example #4
Source File: sagas.test.ts    From pybricks-code with MIT License 6 votes vote down vote up
test('monitorBeforeInstallPrompt', async () => {
    const saga = new AsyncSaga(app);

    fireEvent(window, createEvent('beforeinstallprompt', window));

    const action = await saga.take();
    expect(action).toStrictEqual(appDidReceiveBeforeInstallPrompt());

    await saga.end();
});
Example #5
Source File: Radio.test.tsx    From chroma-react with MIT License 6 votes vote down vote up
test('it calls the provided onChange event on-click', async () => {
  const props = getBaseProps();
  const handleChange = jest.fn();
  const { findByTestId } = renderWithTheme(
    <Radio {...props} onChange={handleChange} data-testid={testId} />
  );

  const input = await findByTestId(testId);
  fireEvent.click(input);
  expect(handleChange).toBeCalledTimes(1);
});
Example #6
Source File: ChatMessages.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 6 votes vote down vote up
test('Should render for multi-search', async () => {
  defineUrl('http://localhost:3000/chat/2?search=8');

  const { getByTestId } = render(chatMessages);

  await waitFor(() => {
    const container: any = document.querySelector('.messageContainer');
    fireEvent.scroll(container, { target: { scrollY: 0 } });
    fireEvent.click(getByTestId('loadMoreMessages'));
  });
});
Example #7
Source File: Checkbox.test.tsx    From chroma-react with MIT License 6 votes vote down vote up
test('it calls the provided onChange event on-click', async () => {
  const props = getBaseProps();
  const handleChange = jest.fn();
  const { findByTestId } = renderWithTheme(
    <Checkbox {...props} onChange={handleChange} data-testid={testId} />
  );

  const input = await findByTestId(testId);
  fireEvent.click(input);
  expect(handleChange).toBeCalledTimes(1);
});
Example #8
Source File: DuplicateFileDialog.test.tsx    From pybricks-code with MIT License 5 votes vote down vote up
describe('duplicate button', () => {
    it('should accept the dialog Duplicate is clicked', async () => {
        const [user, dialog, dispatch] = testRender(<DuplicateFileDialog />, {
            explorer: {
                duplicateFileDialog: { isOpen: true, fileName: 'source.file' },
            },
        });

        const button = dialog.getByRole('button', { name: 'Duplicate' });

        // have to type a new file name before Duplicate button is enabled
        const input = dialog.getByRole('textbox', { name: 'File name' });
        await waitFor(() => expect(input).toHaveFocus());
        await user.type(input, 'new', { skipClick: true });
        await waitFor(() => expect(button).not.toBeDisabled());

        await user.click(button);
        expect(dispatch).toHaveBeenCalledWith(
            duplicateFileDialogDidAccept('source.file', 'new.file'),
        );
    });

    it('should accept the dialog when enter is pressed in the text input', async () => {
        const [user, dialog, dispatch] = testRender(<DuplicateFileDialog />, {
            explorer: {
                duplicateFileDialog: { isOpen: true, fileName: 'source.file' },
            },
        });

        // have to type a new file name before Duplicate button is enabled
        const input = dialog.getByRole('textbox', { name: 'File name' });
        await waitFor(() => expect(input).toHaveFocus());
        await user.type(input, 'new{Enter}', { skipClick: true });

        expect(dispatch).toHaveBeenCalledWith(
            duplicateFileDialogDidAccept('source.file', 'new.file'),
        );
    });

    it('should cancel when user clicks close button', async () => {
        const [user, dialog, dispatch] = testRender(<DuplicateFileDialog />, {
            explorer: {
                duplicateFileDialog: { isOpen: true, fileName: 'source.file' },
            },
        });

        const button = dialog.getByRole('button', { name: 'Close' });

        await waitFor(() => expect(button).toBeVisible());

        await user.click(button);
        expect(dispatch).toHaveBeenCalledWith(duplicateFileDialogDidCancel());
    });

    it('should cancel when user user presses esc key', async () => {
        const [user, dialog, dispatch] = testRender(<DuplicateFileDialog />, {
            explorer: {
                duplicateFileDialog: { isOpen: true, fileName: 'source.file' },
            },
        });

        await waitFor(() =>
            expect(dialog.getByRole('textbox', { name: 'File name' })).toHaveFocus(),
        );
        // FIXME: use userEvent instead of fireEvent
        // blocked by https://github.com/palantir/blueprint/pull/5349
        // await user.keyboard('{Escape}');
        user;
        fireEvent.keyDown(document.activeElement ?? document, {
            key: 'Escape',
            keyCode: 27,
            which: 27,
        });

        expect(dispatch).toHaveBeenCalledWith(duplicateFileDialogDidCancel());
    });
});
Example #9
Source File: ChatMessages.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 5 votes vote down vote up
test('Load more messages', async () => {
  const searchQuery = {
    query: SEARCH_QUERY,
    variables: {
      filter: {},
      contactOpts: { limit: DEFAULT_CONTACT_LIMIT },
      messageOpts: { limit: DEFAULT_MESSAGE_LIMIT },
    },
    data: {
      search: [
        {
          group: null,
          contact: {
            id: '2',
            name: 'Effie Cormier',
            phone: '987654321',
            maskedPhone: '98****321',
            lastMessageAt: '2020-06-29T09:31:47Z',
            status: 'VALID',
            fields: '{}',
            bspStatus: 'SESSION_AND_HSM',
            isOrgRead: true,
          },
          messages,
        },
      ],
    },
  };

  cache.writeQuery(searchQuery);
  const client = new ApolloClient({
    cache: cache,
    assumeImmutableResults: true,
  });

  const chatMessages = (
    <MemoryRouter>
      <ApolloProvider client={client}>
        <ChatMessages contactId="2" />
      </ApolloProvider>
    </MemoryRouter>
  );

  const { getByTestId } = render(chatMessages);

  await waitFor(() => {
    const container: any = document.querySelector('.messageContainer');
    fireEvent.scroll(container, { target: { scrollY: 0 } });
    fireEvent.click(getByTestId('loadMoreMessages'));
  });
});
Example #10
Source File: Plugin.spec.tsx    From react-native-performance with MIT License 5 votes vote down vote up
setupPlugin = () => {
  const { instance, renderer, sendEvent, onSend } =
    TestUtils.renderPlugin(Plugin);

  // First measure on Android is always 0 and is ignored by plugin
  sendEvent("addRecord", {
    frameCount: 0,
    thread: "JS",
    time: 500,
  });
  sendEvent("addRecord", {
    frameCount: 0,
    thread: "UI",
    time: 500,
  });

  return {
    addMeasure: ({
      JS,
      UI,
      time,
    }: {
      JS: number;
      UI: number;
      time?: number;
    }) => {
      sendEvent("addRecord", {
        frameCount: JS,
        thread: "JS",
        time: time || 500,
      });
      sendEvent("addRecord", {
        frameCount: UI,
        thread: "UI",
        time: time || 500,
      });
    },
    clickStart: () => fireEvent.click(renderer.getByText("Start Measuring")),
    clickStop: () => fireEvent.click(renderer.getByText("Stop Measuring")),
    expectToMatchSnapshot: () => {
      expect(
        (renderer.baseElement as HTMLBodyElement).textContent
      ).toMatchSnapshot();
      expect(renderer.baseElement).toMatchSnapshot();
    },
    setTimeLimit: (limit: number) => {
      const input = renderer.getByLabelText("Time limit");
      fireEvent.change(input, { target: { value: limit } });
    },
    clickTimeLimitCheckbox: () => {
      const checkbox = renderer.getByLabelText("Time limit enabled");
      fireEvent.click(checkbox);
    },

    renderer,
    instance,
    onSend,
  };
}
Example #11
Source File: DayPicker.test.tsx    From chroma-react with MIT License 5 votes vote down vote up
it('prevents dates that match disableDay', () => {
  const onDayChange = jest.fn();
  const onTextChange = jest.fn();
  const view = render({
    // Nov 15, 2021, 6AM UTC
    value: new Date('2021-11-15T06:00:00.000Z'),
    onDayChange,
    onTextChange,
    // Disable even dates
    disableDay: (date) => date.getDate() % 2 === 0,
    parseDate: parser('M/D/YYYY'),
  });

  // Open the calendar by focusing the text field.
  const input = view.getByRole('textbox');
  fireEvent.focus(input);

  for (let day = 1; day <= 30; day++) {
    const dayEl = view.getByLabelText(
      dayjs(`2021-11-01T00:00:00.000Z`)
        .set('date', day)
        .format(DAY_LABEL_FORMAT)
    );

    if (day % 2 === 0) {
      expect(dayEl.getAttribute('aria-disabled')).toStrictEqual('true');
      fireEvent.click(dayEl);
      expect(onDayChange).not.toHaveBeenCalled();
    } else {
      expect(dayEl.getAttribute('aria-disabled')).toStrictEqual('false');
      fireEvent.click(dayEl);
      expect(onDayChange).toHaveBeenCalledTimes(1);
      expect(onDayChange.mock.calls[0][0].toISOString()).toStrictEqual(
        dayjs(`2021-11-01T00:00:00.000Z`).set('date', day).toISOString()
      );
    }
    onDayChange.mockClear();
  }

  // Try typing an invalid date
  fireEvent.change(input, { target: { value: '11/16/2021' } });
  expect(onTextChange).toHaveBeenCalledWith('11/16/2021');
  expect(onDayChange).not.toHaveBeenCalled();
  expect(input).toMatchObject({ value: '11/16/2021' });

  // Blur the input and assert that the intermediate value is wiped.
  fireEvent.blur(input);
  expect(input.getAttribute('value')).toStrictEqual('11/15/2021');
});
Example #12
Source File: List.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 5 votes vote down vote up
describe('<List />', () => {
  test('should have loading', () => {
    const { getByText } = render(list);
    waitFor(() => {
      expect(getByText('Loading...')).toBeInTheDocument();
    });
  });

  test('should have add new button', async () => {
    const { container } = render(list);
    await waitFor(() => {
      expect(container.querySelector('button.MuiButton-containedPrimary')).toBeInTheDocument();
    });
  });

  test('should have a table, search and reset', async () => {
    const { container, getByTestId } = render(list);

    await waitFor(() => {
      expect(container.querySelector('table')).toBeInTheDocument();
      fireEvent.change(getByTestId('searchInput')?.querySelector('input'), {
        target: { value: 'Unread' },
      });
    });

    await waitFor(() => {
      fireEvent.submit(getByTestId('searchForm'));
      fireEvent.click(getByTestId('resetButton'));
    });
  });

  test('list has proper headers', async () => {
    const { container } = render(list);
    await waitFor(() => {
      const tableHead = container.querySelector('thead');
      const { getByText } = within(tableHead);
      expect(getByText('LABEL')).toBeInTheDocument();
      expect(getByText('DESCRIPTION')).toBeInTheDocument();
      expect(getByText('KEYWORDS')).toBeInTheDocument();
      expect(getByText('ACTIONS')).toBeInTheDocument();
    });
  });

  test('A row in the table should have an edit and delete button', async () => {
    const { container } = render(list);

    await waitFor(() => {
      const tableRow = container.querySelector('tbody tr');
      const { getByLabelText } = within(tableRow);
      expect(getByLabelText('Edit')).toBeInTheDocument();
      expect(getByLabelText('Delete')).toBeInTheDocument();
    });
  });
});
Example #13
Source File: DayPicker.test.tsx    From chroma-react with MIT License 5 votes vote down vote up
it('prevents dates before minDate and after maxDate', () => {
  const onDayChange = jest.fn();
  const onTextChange = jest.fn();
  const view = render({
    // Nov 5, 2021, 6AM UTC
    value: new Date('2021-11-05T06:00:00.000Z'),
    onDayChange,
    onTextChange,
    // Nov 3, 2021, 6AM UTC
    minDate: new Date('2021-11-03T06:00:00.000Z'),
    // Nov 7, 2021, 6AM UTC
    maxDate: new Date('2021-11-07T06:00:00.000Z'),
    parseDate: parser('M/D/YYYY'),
  });

  // Open the calendar by focusing the text field.
  const input = view.getByRole('textbox');
  fireEvent.focus(input);

  // Assert valid dates are enabled.
  for (const label of [
    'Thu Nov 04 2021',
    'Fri Nov 05 2021',
    'Sat Nov 06 2021',
    'Sun Nov 07 2021',
  ]) {
    const day = view.getByLabelText(label);
    expect(day.getAttribute('aria-disabled')).toStrictEqual('false');

    fireEvent.click(day);
    expect(onDayChange).toHaveBeenCalledTimes(1);
    expect(onDayChange.mock.calls[0][0].toISOString()).toStrictEqual(
      // Interesting implicit assertion: assert that the returned date
      // is at midnight, which is actually _before_ the specified
      // `minDate` value.
      `2021-11-${label.split(' ')[2]}T00:00:00.000Z`
    );
    onDayChange.mockClear();
  }

  // Assert invalid dates are disabled.
  for (const label of [
    'Mon Nov 01 2021',
    'Tue Nov 02 2021',
    'Mon Nov 08 2021',
    'Tue Nov 09 2021',
  ]) {
    const day = view.getByLabelText(label);
    expect(day.getAttribute('aria-disabled')).toStrictEqual('true');

    fireEvent.click(day);
    expect(onDayChange).not.toHaveBeenCalled();
  }

  // Try typing an invalid date
  fireEvent.change(input, { target: { value: '11/2/2021' } });
  expect(onTextChange).toHaveBeenCalledWith('11/2/2021');
  expect(onDayChange).not.toHaveBeenCalled();
  expect(input).toMatchObject({ value: '11/2/2021' });

  // Blur the input and assert that the intermediate value is wiped.
  fireEvent.blur(input);
  expect(input.getAttribute('value')).toStrictEqual('11/5/2021');
});
Example #14
Source File: index.test.ts    From d3-render with MIT License 4 votes vote down vote up
describe('Render', () => {
  it('should return empty selection', () => {
    expect(render('.test', [])).toEqual({ _groups: [], _parents: [] });
  });

  it('should render text element in svg with multiple attributes', () => {
    const svg = getExampleDOM('svg');
    const data = [
      {
        append: 'text',
        text: 'test',
        x: 5,
        y: 5,
        onClick: () => {},
      },
    ];

    render(svg, data);

    expect(svg.nodeName).toEqual('SVG');
    expect(svg.querySelector('text')).toBeTruthy();
    expect(getByText(svg, 'test')).toBeTruthy();

    data.forEach(d => {
      Object.keys(d).map(key => {
        const keyType = getKeyType(key);

        if (keyType === 'attribute') {
          const realValue = d[key];
          const testValue = svg.querySelector('text').getAttribute(key);

          expect(testValue).toEqual(realValue.toString());
        }
      });
    });
  });

  it("should render rect of class 'rect1' with inline styles", () => {
    const svg = getExampleDOM('svg');
    const data = [
      {
        append: 'rect',
        class: 'rect1',
        fill: 'red',
        style: {
          stroke: 'black',
          fillOpacity: 0.5,
        },
      },
    ];

    render(svg, data);

    const rect = svg.querySelector('.rect1');

    expect(rect.getAttribute('style')).toEqual(
      'stroke: black; fill-opacity: 0.5;'
    );
  });

  it("should render group of id '#group1' with children", () => {
    const svg = getExampleDOM('svg');
    const data = [
      {
        append: 'g',
        id: 'group1',
        children: [
          {
            append: 'circle',
            r: 10,
          },
        ],
      },
    ];

    render(svg, data);

    const group = svg.querySelector('#group1');
    const circle = group.querySelector('circle');

    expect(circle).toBeTruthy();
    expect(circle.getAttribute('r')).toEqual('10');
  });

  it('should render rect with initial width from transition object', () => {
    const svg = getExampleDOM('svg');

    const data = [
      {
        append: 'rect',
        width: { enter: 100, exit: 0 },
      },
    ];

    render(svg, data);

    const rect = svg.querySelector('rect');
    expect(rect.getAttribute('width')).toEqual('0');
  });

  it('should render rect with an onClick handler', () => {
    const svg = getExampleDOM('svg');
    const onClick = jest.fn();
    const data = [
      {
        append: 'rect',
        width: 100,
        height: 100,
        onClick,
      },
    ];

    render(svg, data);

    const rect = svg.querySelector('rect');
    fireEvent(rect, new MouseEvent('click'));
    expect(onClick).toBeCalledWith(
      expect.objectContaining({
        isTrusted: false,
      }),
      expect.objectContaining({
        append: 'rect',
      })
    );
  });

  it('should render ellipse with a function attribute value', () => {
    const svg = getExampleDOM('svg');
    const rxMock = jest.fn();
    const data = [
      {
        append: 'ellipse',
        rx: (d, i) => {
          rxMock(d, i);
          return 100;
        },
        ry: 50,
      },
    ];

    render(svg, data);

    const ellipse = svg.querySelector('ellipse');
    expect(ellipse.getAttribute('rx')).toEqual('100');
    expect(rxMock).toBeCalledWith(data[0], 0);
  });

  it('should render div with text', () => {
    const body = getExampleDOM('body');
    const data = [
      {
        append: 'div',
        text: 'Text in div',
      },
    ];

    render(body, data);
    const div = body.querySelector('div');

    expect(div).toBeTruthy();
    expect(getByText(body, 'Text in div')).toBeTruthy();
  });

  it('should render div with html', () => {
    const body = getExampleDOM('body');
    const data = [
      {
        append: 'div',
        html: '<p>Text in paragraph</p>',
      },
    ];

    render(body, data);
    const div = body.querySelector('div');
    const paragraph = div.querySelector('p');

    expect(paragraph).toBeTruthy();
    expect(getByText(paragraph, 'Text in paragraph')).toBeTruthy();
  });

  it('should render data with null values', () => {
    const body = getExampleDOM('body');
    const data = [null];

    // @ts-ignore
    render(body, data);
    // const div = body.querySelector('div');
    // const paragraph = div.querySelector('p');

    expect(body).toBeTruthy();
  });

  it('should render data with a call function', () => {
    const mockCall = jest.fn();
    const svg = getExampleDOM('svg');
    const data = [
      {
        append: 'g',
        call: mockCall,
      },
    ];

    render(svg, data);
    const g = svg.querySelector('g');

    expect(g).toBeTruthy();
    expect(mockCall).toBeCalledWith({ _groups: [[g]], _parents: [null] });
  });

  it('should render svg with viewBox attribute instead of view-box', () => {
    // Ensure certain svg attributes are not converted from camel to kebab case.
    const div = getExampleDOM('div');
    const data = [
      {
        append: 'svg',
        viewBox: '0 0 100 100',
      },
    ];

    render(div, data);
    const svg = div.querySelector('svg');
    expect(svg.getAttribute('viewBox')).toEqual('0 0 100 100');
  });
});