Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React testing library in Typescript

I'm following a tutorial on React.js testing Library and trying to follow along in Typescript. Although after following along with the first test I'm already encountering a few issues and am wondering what should be different in a test written in Typescript.

App.ts

function App() {
    return (
        <div className="container my-5">
            <form>
                <div className="mb-3">
                    <label htmlFor="email" className="form-label">
                        Email Address
                    </label>
                    <input
                        type="email"
                        id="email"
                        name="email"
                        className="form-control"
                    />
                </div>
                <div className="mb-3">
                    <label htmlFor="password" className="form-label">
                        Password
                    </label>
                    <input
                        type="password"
                        id="password"
                        name="password"
                        className="form-control"
                    />
                </div>
            </form>
        </div>
    );
}

export default App;

App.test.tsx

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

test("inputs should be initially empty", () => {
    render(<App />);
    const emailInputElement = screen.getByRole("textbox");
    const passwordInputElement = screen.getByLabelText(/password/);
    expect(emailInputElement.value).toBe("");
    expect(passwordInputElement.value).toBe("");
});

I'm receiving an error "Property 'value' does not exist on type 'HTMLElement" on:

expect(emailInputElement.value).toBe("");
expect(passwordInputElement.value).toBe("");

Do these need to be explained differently on Typescript?

like image 341
code4cash Avatar asked Aug 16 '26 08:08

code4cash


2 Answers

You are getting this error because screen.getByRole and screen.getByLabelText returns HTMLElement object and it doesn´t have value prop.

There are 2 ways to get it working:

  1. explicitly define the return type as HTMLInputElement (it has value prop).
import { render, screen } from "@testing-library/react";
import App from "./App";

test("inputs should be initially empty", () => {
  render(<App />);

   const emailInputElement = screen.getByRole<HTMLInputElement>("textbox");
   const passwordInputElement = screen.getByLabelText<HTMLInputElement>(/password/i);

   expect(emailInputElement.value).toBe("");
   expect(passwordInputElement.value).toBe("");
});
  1. Use @testing-library/jest-dom library -> it provides a set of custom jest matchers that you can use to extend jest. You can check more here.
import "@testing-library/jest-dom/extend-expect";
import { render, screen } from "@testing-library/react";
import App from "./App";

test("inputs should be initially empty", () => {
  render(<App />);

   const emailInputElement = screen.getByRole("textbox");
   const passwordInputElement = screen.getByLabelText(/password/i);  

   expect(emailInputElement).toHaveValue("");
   expect(passwordInputElement).toHaveValue("");
});

like image 74
Luis Paulo Pinto Avatar answered Aug 17 '26 22:08

Luis Paulo Pinto


You can define type for both text box as HTMLInputElement also where you are targeting password in your actual code it's case sensitive so always use regular expression to avoid tests failing ie (/password/i)

  render(<App/>);
  const emailInputElement: HTMLInputElement = screen.getByRole("textbox");
  const passwordInputElement: HTMLInputElement =
    screen.getByLabelText(/password/i);
  expect(emailInputElement.value).toBe("");
  expect(passwordInputElement.value).toBe("");
});
like image 39
Aman Sadhwani Avatar answered Aug 17 '26 22:08

Aman Sadhwani



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!