lbr*_*ile 6 forms validation jestjs react-bootstrap react-testing-library
我无法使用 React-bootstrap 测试表单的正确验证。\n我想看到,当输入模式无效时,一旦验证表单,就会显示无效的反馈文本。
\n带有测试的工作codesandbox:https://codesandbox.io/s/flamboyant-cerf-7t7jq
\nimport React, { useState } from "react";\n\nimport { Form, Button, InputGroup } from "react-bootstrap";\n\nexport default function App(): JSX.Element {\n const [validated, setValidated] = useState<boolean>(false);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n setValidated(true);\n };\n\n return (\n <Form\n className="col-12 col-lg-5 trans-form"\n noValidate\n validated={validated}\n onSubmit={handleSubmit}\n >\n <InputGroup className="my-2">\n <InputGroup.Prepend>\n <InputGroup.Text>Receiver Public Key</InputGroup.Text>\n </InputGroup.Prepend>\n <Form.Control\n role="textbox"\n className="text-truncate rounded-right"\n type="text"\n pattern="[A-Za-z0-9]{5}"\n required\n />\n <Form.Control.Feedback\n className="font-weight-bold"\n type="invalid"\n role="alert"\n >\n Length or format are incorrect!\n </Form.Control.Feedback>\n </InputGroup>\n\n <Button\n role="button"\n className="mt-2 font-weight-bold"\n variant={"primary"}\n type="submit"\n block\n >\n Sign\n </Button>\n </Form>\n );\n}\n
Run Code Online (Sandbox Code Playgroud)\nimport React from "react";\nimport { render, screen, waitFor } from "@testing-library/react";\nimport userEvent from "@testing-library/user-event";\nimport "@testing-library/jest-dom";\n\nimport App from "../src/App";\n\ndescribe("form validation", () => {\n test("invalid receiver public key length", async () => {\n render(<App />);\n userEvent.click(screen.getByRole("button"));\n userEvent.type(screen.getByRole("textbox"), "invalid");\n expect(screen.getByRole("textbox")).toHaveValue("invalid");\n expect(\n await screen.findByText("Length or format are incorrect!")\n ).toBeVisible();\n });\n\n // this test fails, making it seem like the invalid-feedback is always present\n test("valid receiver public key length", async () => {\n render(<App />);\n userEvent.click(screen.getByRole("button"));\n userEvent.type(screen.getByRole("textbox"), "valid");\n expect(screen.getByRole("textbox")).toHaveValue("valid");\n await waitFor(() => {\n expect(\n screen.queryByText("Length or format are incorrect!")\n ).not.toBeVisible(); // \xe2\x86\x90 FAILS\n });\n });\n});\n
Run Code Online (Sandbox Code Playgroud)\n第二次测试失败
\n\n我最终使用Formik获得相同(但更好)的功能,这也允许我有条件地呈现错误消息:
更新了codesandbox
// App.js
import React from "react";
import * as yup from "yup";
import { Formik, ErrorMessage, Field } from "formik";
import { Form, Button, InputGroup } from "react-bootstrap";
export default function App(): JSX.Element {
return (
<Formik
validationSchema={yup.object().shape({
from: yup
.string()
.matches(/^[A-Za-z0-9]{5}$/, "invalid format")
.required("from field is required")
})}
onSubmit={async (data, { setSubmitting }) => {
setSubmitting(true);
alert("submitted: " + data.from);
setSubmitting(false);
}}
initialValues={{ from: "" }}
>
{({ handleSubmit, isSubmitting, touched, errors }) => (
<Form
className="col-12 col-lg-5 trans-form"
noValidate
onSubmit={handleSubmit}
>
<InputGroup className="my-2">
<InputGroup.Prepend>
<InputGroup.Text>Label</InputGroup.Text>
</InputGroup.Prepend>
<Field
as={Form.Control}
role="textbox"
aria-label="from input"
type="text"
name="from"
required
isInvalid={!!touched.from && !!errors.from}
isValid={!!touched.from && !errors.from}
/>
<ErrorMessage
name="from"
render={(errorMessage) => (
<Form.Control.Feedback
className="font-weight-bold"
type="invalid"
role="alert"
aria-label="from feedback"
>
{errorMessage}
</Form.Control.Feedback>
)}
/>
</InputGroup>
<Button
role="button"
className="mt-2 font-weight-bold"
variant={"primary"}
type="submit"
block
disabled={isSubmitting}
>
Sign
</Button>
</Form>
)}
</Formik>
);
}
// App.test.js
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import "@testing-library/jest-dom";
import App from "../src/App";
describe("form validation", () => {
test("empty", async () => {
render(<App />);
const input = screen.getByRole("textbox", { name: /From Input/i });
input.focus();
input.blur(); // cause an error
expect(input).toHaveValue("");
const alert = await screen.findByRole("alert", { name: /From Feedback/i });
expect(alert).toBeInTheDocument();
expect(alert).toHaveTextContent("from field is required");
});
test("invalid length", async () => {
render(<App />);
const input = screen.getByRole("textbox", { name: /From Input/i });
const text = "aaaaaa";
userEvent.type(input, text);
input.blur(); // cause an error
expect(input).toHaveValue(text);
const alert = await screen.findByRole("alert", { name: /From Feedback/i });
expect(alert).toBeInTheDocument();
expect(alert).toHaveTextContent("invalid format");
});
test("valid length", async () => {
render(<App />);
const input = screen.getByRole("textbox", { name: /From Input/i });
const text = "bbbbb";
userEvent.type(input, text);
input.blur();
expect(input).toHaveValue(text);
expect(
screen.queryByRole("alert", { name: /From Feedback/i })
).not.toBeInTheDocument();
});
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5628 次 |
最近记录: |