-
Notifications
You must be signed in to change notification settings - Fork 32
Description
Overview
The render function provides two options for changing how a component gets rendered into the DOM: componentOptions.target and renderOptions.container. It returns a result.container element.
const { container } = render(Component, componentOptions, renderOptions)componentOptions.targetis the target element the component is rendered into- Defaults to an empty
<div>that we create
- Defaults to an empty
renderOptions.containeris the element thattargetis inserted into- Defaults to
document.body
- Defaults to
result.containerreturnsrenderOptions.container
These option names and their behaviors are different in confusing ways from other testing-library frameworks that make svelte-testing-library a little more difficult to use than its siblings. The primary issue is that by default we return document.body rather than the created div for result.container.
Expectations
| Value | Svelte | React / Preact / Vue |
|---|---|---|
| Document root option | container |
baseElement |
| Mount point option | target |
container |
| Returned container | Document root | Mount point |
const { container, component } = render(Comp, { foo: 'bar' })<body> <!-- container (baseElement) -->
<div> <!-- target (container) -->
<Comp foo="bar" /> <!-- component -->
</div>
</body>The main issue I have is result.container is one level higher than I expect. The most common way I notice this is that I expect container.firstChild to be my component's first node. Instead, it is container.firstElement.firstElement.
This expectation comes from the react-testing-library docs:
containerThe containing DOM node of your rendered React Element (rendered using ReactDOM.render). It's a
div. This is a regular DOM node, so you can callcontainer.querySelectoretc. to inspect the children.Tip: To get the root element of your rendered element, use
container.firstChild.
Proposed changes
Since there are definitely breaking changes on the horizon due to Svelte moving on from v3, I think there's an opportunity here to align the render API with all the other libraries.
I think a small but effective change set would be:
- Rename the existing
containeroption tobaseElement - Return
baseElement(root) asresult.baseElement - Return
target(the wrapping<div>) asresult.container - If
targetis provided, use it as thebaseElementand do not create/insert any other elements- This is the same behavior as (react|preact|vue)-testing-library
I think there are a few other changes we could consider:
- Rename the existing
targetoption tocontainer- Pro: this would align better with the name of the return value
- Con: would misalign us with the name of the Svelte option
- Collapse
componentOptionsandrenderOptionsinto a singleoptionsobject- Pro: aligns a little better with
vue-testing-library - Con: runs the risk of conflicts between Svelte options and testing-library options
- Pro: aligns a little better with
Relates to #312