Jest.js 按回车键提交react-testing-library中的表单不起作用

puruo6ea  于 2023-08-01  发布在  Jest
关注(0)|答案(7)|浏览(143)

说明:

我试图测试当用户按下“Enter”键时表单提交。我有一个关于按下Submit按钮的通过测试,但我也想确保表单使用键盘提交(方便和a11y)。

编码:

test("should submit when pressing enter", () => {
  const handleSubmit = jest.fn();
  const { getByLabelText } = render(<App handleSubmit={handleSubmit} />);
  const input = getByLabelText("Name:");

  fireEvent.change(input, { target: { value: "abc" } });
  fireEvent.keyPress(input, { key: "Enter", code: 13, charCode: 13 });

  expect(handleSubmit).toHaveBeenCalled();
});

字符串
下面是一个CodeSandbox,它只需要最少的代码。

mum43rcc

mum43rcc1#

不太清楚交互的源代码是什么,但可以在input上调用submit,并且它似乎修复了沙箱中的测试:

fireEvent.submit(input);

字符串

vx6bjr1n

vx6bjr1n2#

以下为我工作:

import userEvent from "@testing-library/user-event";
import { render } from "@testing-library/react";

test("should submit when pressing enter", () => {
  const handleSubmit = jest.fn();
  const { getByLabelText } = render(<App handleSubmit={handleSubmit} />);
  const input = getByLabelText("Name:");

  userEvent.type(input, "abc{enter}");

  expect(handleSubmit).toHaveBeenCalled();
});

字符串

svujldwt

svujldwt3#

您可以按按钮提交,但事件目标将是按钮而不是表单。要解决此问题,请执行以下操作:

  • 提交表格
  • 表单上的useRef
  • 表单上的ByTestId

只有当表单具有可访问的名称时,才可以提交表单。在这个意义上,使用role="my-form"(ByRole)或aria-label="form's purpose"(ByLabelText或ByRole(“form”))。

import "@testing-library/jest-dom/extend-expect";
import { getByRole, fireEvent } from '@testing-library/dom';

test("test form", () => {
  const div = document.createElement("div");

  div.innerHTML = `
  <form role="my-form">
    <label for="first_name">
      First Name:
      <input id="first_name" type="text" />
    </label>
    <button type="submit">Submit</button>
  </form>
  `;

  const handleSubmit = jest.fn();
  div.querySelector('form').onsubmit = handleSubmit;

  fireEvent.submit(getByRole(div, "my-form"));
  expect(handleSubmit).toHaveBeenCalledTimes(1);
});

字符串

mqxuamgl

mqxuamgl4#

我遵循了above的答案,但它对我不起作用,因为我使用keydown侦听器来检查我的输入。
请记住,只使用e.key,而不是e.keyCode/e.whichdeperecatedhttps://stackoverflow.com/a/4471635/8798220

import React, { useState } from "react";
import userEvent from "@testing-library/user-event";
import { render } from "@testing-library/react";

const Input = () => {
  const [value, setValue] = useState("");

  const handleEnter = (e) => {
    if (e.key === "Enter") {
      const value = e.target.value;
      // API CALLING / LOGIC
    }
  };

  return (
    <input
      placeholder="Search..."
      value={value}
      onChange={(e) => setValue(e.target.value)}
      onKeyDown={handleEnter}
    />
  );
};

it("should submit when pressing enter", async () => {
  const text = "hello";

  render(<Input />);

  const input = screen.getByPlaceholderText("Search...");
  await userEvent.type(input, `${text}[Enter]`);

  expect(input).toHaveValue(text);
  // check about enter logic.
});

字符串

ogsagwnx

ogsagwnx5#

我找到了一种方法,可以在不做任何更改或不添加新库的情况下强制执行它,如下所示

const btnDeepPropsKey = Object.keys(
  wrapper.getByTestId('input-search')
)?.find(item => item?.includes('__reactProps'))

await waitFor(async () =>
  (wrapper.getByTestId('input-search') as any)?.[
    btnDeepPropsKey
  ]?.onKeyPress({ key: 'Enter' })
)

字符串
如果你够不到那个 prop 你也可以记录它

console.log(wrapper.getByTestId("input-search"))


请注意,如果您尝试访问上面日志中显示的任何其他onKeyPress prop ,某些状态可能会丢失

mnemlml8

mnemlml86#

为了模拟键盘显示/隐藏,我首先关注输入,然后模拟打字。通过这种方式,您可以触发onSubmitEditing事件来模拟键盘上按下的提交按钮。

import { fireEvent } from '@testing-library/react-native'

const input = getByTestId('input');
fireEvent.focus(input);
fireEvent.changeText(input, 'hello world')
fireEvent.submitEditing(input);

字符串

koaltpgm

koaltpgm7#

您没有向fireEvent.keyDown事件传递正确的选项。尝试将keyCode: 13key: "enter"沿着传递
下面这段代码对我来说很有用

it('Check if added todo show in list with label', () => {
  render(<TodoApp/>)
  const input = screen.getByTestId('add-todo')

  fireEvent.change(input, {target: {value: 'Task with label @health'}});
  fireEvent.keyDown(input, {key: 'enter', keyCode: 13})

  const todoList = screen.getByTestId('todo-list')
  expect(todoList).toHaveTextContent('health')
});

字符串

相关问题