Challenge 2: Testing a Password-Match Field — Possible Solution ==================================================================== it("shows a mismatch message only when the passwords differ", async () => { render(); expect(screen.queryByText("Passwords do not match")).not.toBeInTheDocument(); await userEvent.type(screen.getByLabelText("Password"), "hunter2"); await userEvent.type(screen.getByLabelText("Confirm Password"), "hunter3"); expect(await screen.findByText("Passwords do not match")).toBeInTheDocument(); await userEvent.clear(screen.getByLabelText("Confirm Password")); await userEvent.type(screen.getByLabelText("Confirm Password"), "hunter2"); expect(screen.queryByText("Passwords do not match")).not.toBeInTheDocument(); }); WHY THIS WORKS AS AN ANSWER ------------------------------ The FIRST assertion uses queryByText (not getByText) specifically because the message is expected to be ABSENT at that point — exactly this chapter's conditional-rendering pattern (queryBy to confirm absence) and Chapter 3's own rule that getBy would incorrectly throw in a situation where "not found" is the correct, expected outcome. Typing two DIFFERENT passwords into the two fields (via userEvent.type, preferred per this chapter) triggers the mismatch condition. findByText is used for the appearance check rather than getByText, since the message may only appear after a state update triggered by the typing — treating it as a potentially-async change is the safer default consistent with this chapter's own toggle example. The final section demonstrates the message disappearing again once the passwords are made to match — clearing and retyping the confirm field with the SAME value as the password field, then reverting to queryByText to confirm absence once more. Testing both the "message appears" and "message disappears" transitions (not just one direction) verifies the conditional logic actually reacts to changes correctly in both directions, not just that it can show the message once.