'Test url params in react-testing-library without react-router
I have a widget that uses React but not the react-router package. One component checks for the existence of a url param via the URLSearchParams API and then opens or closes using styling:
function App() {
const openWidget =
new URLSearchParams(window.location.search)
.get("openWidget")
?.toLowerCase() === "true";
const [show, setShow] = useState(openWidget);
return (<StyledComponent $show={show}>something</StyledComponent>) // set height to 0 or 100vh based on $show
}
However, I can't figure out how to test this in rtl. My current test is like so:
const location = {
...window.location,
search: "openWidget=true",
};
Object.defineProperty(window, "location", {
value: location,
});
customRender(<ChatWindow />, { contextProps: amendedMockContext });
const chatWindow = screen.getByTestId("chat-window");
expect(chatWindow).toHaveStyle("max-height: 100vh");
But when I log out window.location, I get this: { search: '' }. My test throws this error:
- Expected
- max-height: 100vh;
+ max-height: 0px;
What's the right way to test values using search params?
Note: I have other tests using the same customRender and amendedMockContext - it has nothing to do with them.
EDIT: I tried making a minimal reproducible example, and it works just fine: Code Sandbox . But in my actual project it still doesn't work. The code sandbox is set up identically (context, styles, customerRender, everything) yet that one works, and in my own project window.location.search still returns an empty string. I am utterly dumbfounded.
Solution 1:[1]
The last comment in this issue on GitHub Jest repository will help you
https://github.com/facebook/jest/issues/5124#issuecomment-914606939
Using history.replaceState should allow you to change URL search parameter.
Check the other replies in the issue I shared, seems that most of the techniques that were working before to change window.location are not working anymore in the last versions of Jest.
Example
Following your comment about the URL parameter, the point to note here is that, for this test in particular, the only thing that is important for you is the query string, so you can use any valid origin as parameter and eventually, if in another test you need a specific origin, you can pass it to the function. Let me show you an example, created starting from the link I shared.
function changeJSDOMURL(search, url = "https://www.example.com/") {
const newURL = new URL(url);
newURL.search = new URLSearchParams(search);
const href = `${window.origin}${newURL.pathname}${newURL.search}${newURL.hash}`;
history.replaceState(history.state, null, href);
}
// This will consider the default URL, it is OK for your test
changeJSDOMURL({ openWidget: "true" });
// If you need to pass an origin different from the default one
changeJSDOMURL({ openWidget: "true" }, "https://www.something.io");
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
