Challenge 2: Testing an Inactivity Timer — Possible Solution ==================================================================== it("shows the inactivity prompt after 60 seconds", () => { jest.useFakeTimers(); render(); expect(screen.queryByText("Are you still there?")).not.toBeInTheDocument(); act(() => { jest.advanceTimersByTime(60000); }); expect(screen.getByText("Are you still there?")).toBeInTheDocument(); }); WHY THIS WORKS AS AN ANSWER ------------------------------ jest.useFakeTimers() replaces the real setTimeout/setInterval implementations with controllable fake ones BEFORE the component renders, so the component's internal timer (whatever triggers the 60-second inactivity check) never actually waits in real time at all. The first assertion uses queryByText (not getByText) because the message is genuinely expected to be ABSENT immediately after render — zero real or fake time has passed yet — exactly Chapter 3's rule about when queryBy is required instead of getBy. jest.advanceTimersByTime(60000) instantly advances the fake clock by 60,000 milliseconds (60 seconds) — wrapped in act(...) because this directly triggers a state update inside the component (the timer firing), matching this chapter's own toast-dismissal example's use of act() around the same function. Without wrapping it in act(), the following assertion could read a stale render, per Chapter 5's act() explanation. After advancing time, getByText (not queryByText) is now appropriate, since the message SHOULD exist at this point — using getBy here correctly asserts a positive expectation rather than checking for absence.