svelte-testing-library
svelte-testing-library copied to clipboard
Unable to test a non-bound change in the DOM
I am new to testing-library, so I hope I'm not missing anything obvious.
I have a helper class whose methods make changes in a component's DOM, some upon interaction by the user. I am unable to test those changes with fireEvent
or userEvent
. It always fails.
I simplified my use case to a very simple example:
- My svelte component has only a button that modifies the content of a paragraph. The paragraph's content is not bound to a variable intentionally.
- And then I have a test for it. The test
expect(info).toHaveTextContent("Modified by click")
fails but, curiously enough, aconsole.log(paragraph.innerText)
shows the change. - I also have a codesandbox replicating this example.
Code for the component:
<script>
// The text content of the paragraph is purposely not bound
// with any svelte variable. The purpose of this exercise
// is to reduce to the simplest form my use-case which is
// to test changes done in html elements of a svelte component
// by external helper class methods, which do not allow for
// bindings to exist.
const modify = () => {
const par = document.querySelector(".info");
par.innerText = "Modified by click";
};
</script>
<div>
<p class="info" data-testid="info">Click to modify</p>
<button on:click={modify} label="button">Modify</button>
</div>
The code for the test.
import { render, screen, waitFor } from "@testing-library/svelte";
import "@testing-library/jest-dom/extend-expect";
import userEvent from "@testing-library/user-event";
import Component from "./Component.svelte";
it("should modify the text after clicking the button", async () => {
render(Component);
const button = screen.getByRole("button");
userEvent.click(button);
const info = screen.getByTestId("info");
// console.log actually outputs the modified content?
console.log(info.innerText);
// The test fails independently of using waitFor or not.
await waitFor(() => {
expect(info).toHaveTextContent("Modified by click");
});
});
Is this a bug of the library or should I be approaching this test differently?
P.S.: I asked on Discord, both in the testing-library and the svelte communities. I've also researched the documentation and previous issues. While I'm not entirely sure this is a bug, I would very much appreciate an indication of where to seek a solution if the fault resides in my approach.
I have similar problem when testing button clicks that will change the DOM. Sometimes it works, sometimes it doesn't.
I'm nearly sure i'm running into the same issue.
It doesn't seem to re-render the dom after a click event.
I'm experiencing the same symptoms when testing a modal component. An initial test interaction triggers a change in the component (the menu content goes from hidden to rendered); but a subsequent interaction in the same test - that should close the menu - fails to update the 'rendered' output (e.g. as seen in debug()) and the test fails. Inspecting the property that controls visibility shows it has updated :confused: I tried wrapping my expect() in a waitFor() thinking it might simply be a timing issue; but the update render never happens...
edit: in my case it appears that the problem is the use of a transition in the tested component. See #206
It seems that using happy-dom
instead of jsdom
fixes the problem!
The cause of this, specifically, is that jsdom does not support innerText
. There are two available solutions to work around this, neither of which involve svelte-testing-library:
- Switch test runner to Vitest + happy-dom
- happy-dom supports innerText
- In my experience, happy-dom is not a simple drop-in replacement for jsdom, depending on your test suite
- Vitest is great, but also not necessarily a drop-in replacement for Jest
- Switch implementation to use
.textContent
or.innerHTML
instead of.innerText
- Note: both of these have important differences from
innerText
that should be considered before changing your implementation
- Note: both of these have important differences from
@yanick I think this ticket should be considered outside the scope of svelte-testing-library closed. I don't think switching our tests to happy-dom is the right move at this time (see my comment in #286 for reasoning)
@yanick I think this ticket should be considered outside the scope of svelte-testing-library closed. I don't think switching our tests to happy-dom is the right move at this time (see my comment in #286 for reasoning)
Agreed. And having the tests run both under jsdom and happy-dom strikes me as better than flopping around. But that's a talk for #286 :-)