React Testing Library: Render method always returns <body><div/></body>, not the actual content
Asked Answered
R

0

6

I'm new to React Testing Library. I wanted to test a login form that is located inside Login.tsx component.

`

const Login = () => {
  useYupTranslation();
  const dispatch = useAppDispatch();
  const { t } = useTranslation(["common", "loginPage", "buttons", "loginPage"]);
  useDocumentTitle(t("loginPage:header"));
  const navigate = useNavigate();
  const location = useLocation();
  const token = getTokenFromLocalStorage();
  const refreshToken = getRefreshTokenFromLocalStorage();
  const currentTime = new Date().getTime();
  const decodedAccessToken = decodeToken<DecodedToken["accessToken"]>(token!);
  const decodedRefreshToken = decodeToken<DecodedToken["refreshToken"]>(refreshToken!);
  useEffect(() => {
    if (location.search === "?token-expired") {
      toast.error(t("loginPage:logoutNotification"), {
        autoClose: false,
      });
    }
  }, [location, t, token]);

  const loginValidation = Yup.object({
    email: Yup.string().email().required(),
    password: Yup.string().required(),
  });
  const loginFormik = useFormik({
    initialValues: {
      email: "",
      password: "",
    },
    onSubmit: async (values) => {
      await dispatch(loginUser(values));
      navigate(`${location.state ? location.state : "/start"}`);
    },
    validationSchema: loginValidation,
  });
  if (
    token &&
    decodedAccessToken &&
    currentTime / 1000 < decodedAccessToken.exp &&
    decodedRefreshToken &&
    currentTime / 1000 < decodedRefreshToken.exp
  ) {
    return <Navigate to={`${location.state ? location.state : "/start"}`} />;
  }
  return (
    <BasePageLayout img={<Logo width={"100%"} />}>
      <Box
        boxShadow={3}
        maxWidth={800}
        marginY="0.5rem"
        sx={{
          display: "flex",
          backgroundColor: "common.white",
          borderTop: 5,
          borderColor: "primary.main",
          borderRadius: "8px 8px 0px 0px",
        }}
      >
        <Box padding={2}>
          <FormikProvider value={loginFormik}>
            <form onSubmit={loginFormik.handleSubmit} style={{ maxWidth: "520px" }}>
              <Grid container columnSpacing={2} rowSpacing={2.5}>
                <Grid item xs={12} sm={12} md={12} minHeight="100px">
                  <TextFieldFormik id="email" label={t("common:form.email")} name="email" />
                </Grid>
                <Grid item xs={12} sm={12} md={12} minHeight="100px">
                  <PasswordFieldFormik
                    id="password"
                    label={t("common:form.password")}
                    name="password"
                  />
                </Grid>
              </Grid>
              <Button
                type="submit"
                isSubmitting={loginFormik.isSubmitting}
                sx={{ marginY: "1rem" }}
              >
                {t("buttons:submit")}
              </Button>
            </form>
          </FormikProvider>       
        </Box>
      </Box>
    </BasePageLayout>
  );
};

export default Login;

Login component is rendered in App.tsx that looks like this:

function App() {
  return (
    <Suspense
      fallback={
        <Box minHeight={"100vh"} display="flex" justifyContent="center" alignItems="center">
          <CircularProgress />
        </Box>
      }
    >
      <MuiThemeProvider theme={theme}>
        <ThemeProvider theme={theme}>
          <BrowserRouter>
            <Routes>
              <Route element={<PrivateRoute />}>
                <Route path="/start" element={<Start />} />
              </Route>
              <Route path="/login" element={<Login />} />
              <Route path="*" element={<NotFoundPage />} />
            </Routes>
          </BrowserRouter>
          <ToastContainer position="top-center" />
        </ThemeProvider>
      </MuiThemeProvider>
    </Suspense>
  );
}

export default App;

` When I try to render the Login.tsx component in Login.test.tsx file, it just returns div inside a body tags (not the actual component's content) so I can't even get access to the form inputs or submit button to test them.

Login.test.tsx:

import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import Login from "../views/Login";

it("should render input elements", () => {
  render(<Login />);
  
  screen.debug();
});

The output of screen.debug() is just:

<body>
 <div/>
</body>

How can I get access to the actual content of a Login component? Same thing happens for the other components but NotFoundPage.

Radnorshire answered 15/11, 2022 at 12:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.