reactjsjestjsreact-testing-libraryionic-react

RangeError: Invalid string length with jest and @testing-library/react


I am creating tests for an Ionic React app. I noticed that when I use a screen.getBy... provided by the React Testing Library, it does not tell me that the item does not exist. Rather it throws a RangeError: Invalid string length after about 9/10 seconds.

React Testing Library Docs

getBy...: Returns the matching node for a query, and throw a descriptive error if no elements match or if more than one match is found (use getAllBy instead if more than one element is expected).

Test

import { render, screen } from "@testing-library/react";
import App from "./App";

test("some text should not be on screen", async () => {
  render(<App />);

  expect(screen.getByText(/Text/i)).toThrow();
});

/src/App.tsx

/* Core CSS required for Ionic components to work properly */
import "@ionic/react/css/core.css";

/* Basic CSS for apps built with Ionic */
import "@ionic/react/css/normalize.css";
import "@ionic/react/css/structure.css";
import "@ionic/react/css/typography.css";

/* Optional CSS utils that can be commented out */
import "@ionic/react/css/padding.css";
import "@ionic/react/css/float-elements.css";
import "@ionic/react/css/text-alignment.css";
import "@ionic/react/css/text-transformation.css";
import "@ionic/react/css/flex-utils.css";
import "@ionic/react/css/display.css";

/* Theme variables */
import "./theme/variables.css";

/* Imports */
import Auth from "./pages/Auth";
import DevFAB from "./components/DevFAB";
import Home from "./pages/Home";
import Menu from "./components/Menu";
import ResetPassword from "./pages/ResetPassword";
import Settings from "./pages/Settings";
import Unverified from "./pages/Unverified";
import UpdatePassword from "./pages/UpdatePassword";
import {
  IonApp,
  IonContent,
  IonRefresher,
  IonRefresherContent,
  IonRouterOutlet,
  IonSplitPane,
  RefresherEventDetail,
  setupIonicReact,
} from "@ionic/react";
import { AuthContext } from "./contexts/AuthContext";
import { IonReactRouter } from "@ionic/react-router";
import { Redirect, Route, Switch } from "react-router-dom";
import { Suspense, useContext } from "react";

setupIonicReact();

const App: React.FC = () => {
  const { auth } = useContext(AuthContext);

  function handleRefresh(event: CustomEvent<RefresherEventDetail>) {
    window.location.reload()
  }

  return (
    <IonApp>
      <IonContent>
        <IonReactRouter>
          <Suspense>
            <IonRouterOutlet id="auth">
              <Redirect exact from="/" to="/home" />
              <Route exact path="/reset-password" component={ResetPassword} />
              <Route exact path="/unverified" component={Unverified} />
              <Route exact path="/update-password" component={UpdatePassword} />
              <Switch>
                <Route exact path="/auth" component={Auth} />
                <IonSplitPane contentId="main">
                  <Menu />
                  <IonRouterOutlet id="main">
                    <Route render={() => <Redirect to="/home" />} />
                    <Route
                      exact
                      path="/home"
                      render={() =>
                        auth.session ? <Home /> : <Redirect to="/auth" />
                      }
                    />
                    <Route
                      exact
                      path="/update-password"
                      render={() =>
                        auth.session ? (
                          <UpdatePassword />
                        ) : (
                          <Redirect to="/auth" />
                        )
                      }
                    />
                    <Route
                      exact
                      path="/settings"
                      render={() =>
                        auth.session ? (
                          <Settings />
                        ) : (
                          <Redirect to="/auth" />
                        )
                      }
                    />
                  </IonRouterOutlet>
                </IonSplitPane>
              </Switch>
            </IonRouterOutlet>
          </Suspense>
        </IonReactRouter>
        {process.env.NODE_ENV === "development" && <DevFAB />}
        <IonRefresher slot="fixed" onIonRefresh={handleRefresh}>
          <IonRefresherContent></IonRefresherContent>
        </IonRefresher>
      </IonContent>
    </IonApp>
  );
};

export default App;

Error

 FAIL  src/App.test.tsx (9.827 s)
  ✕ some text should not be on screen (9198 ms)

  ● some text should not be on screen
    RangeError: Invalid string length

      at printObjectProperties (node_modules/pretty-format/build/collections.js:174:47)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printListItems (node_modules/pretty-format/build/collections.js:141:19)
      at Object.serialize (node_modules/pretty-format/build/plugins/DOMCollection.js:62:41)
      at printPlugin (node_modules/pretty-format/build/index.js:330:16)
      at printer (node_modules/pretty-format/build/index.js:379:12)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)
      at printObjectProperties (node_modules/pretty-format/build/collections.js:173:21)
      at printComplexValue (node_modules/pretty-format/build/index.js:310:48)
      at printer (node_modules/pretty-format/build/index.js:393:10)

For some reason it is building a very long string somewhere...

If I successfully find the item, my tests pass. But I also want to search for items that do not exist, or only do during development. What am I doing wrong, and how can I solve it?

Thanks in advance


Solution

  • getBy* queries cannot be used to assert non-existence as they will throw error if the element is not found. This is intentional.

    As mentioned here by the creator of RTL himself, you can use queryBy* APIs instead. They are designed specifically for this.

    Official docs