Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to test component slots? #251

Open
alejandroiglesias opened this issue Jan 13, 2021 · 8 comments
Open

How to test component slots? #251

alejandroiglesias opened this issue Jan 13, 2021 · 8 comments

Comments

@alejandroiglesias
Copy link

Hi, I cannot seem to find a way to test component slots. The examples in the readme seem outdated since I cannot seem to make them work. Can you please give an updated example?
I appreciate your help in advance. Best regards.

@Crenshinibon
Copy link

Crenshinibon commented Jan 13, 2021

Hi, I just stumbled upon the same problem. A little investigation revealed that this was made possible with this PR: #33

but was removed later ... at least it's gone by the update to svelte3: #41

You (and I) probably could work around the problem by creating a test specific intermediary component, that wraps your component under test and provides the slots ... not nice but it should work.

@alejandroiglesias
Copy link
Author

I found a solution to test slots on this Svelte issue comment. The idea behind it is to add a createSlots helper function as specified in such comment and use it to populate the $$slots prop of the component. I put such helper in cypress/helpers.js as an exported function:

export function createSlots(slots) {
  // ...
}

And then import it and use in the spec:

// Import helper function in spec:
// import { createSlots } from '../../../cypress/helpers'

mount(
  Content,
  {
    props: {
      $$slots: createSlots({ default: document.createTextNode('Content slot') }),
      $$scope: {}
    }
  }
)

In this case, I pass a text node with the content Content slot, but obviously you can pass any element. I don't know why the $$scope prop is required but it doesn't work without it. A bit hacky solution but it works just fine. Hopefully, we will have a cleaner solution in the future.

@alejandroiglesias
Copy link
Author

Now the challenge I'm facing is how to pass another component into the slot? For example, to test components that are meant to be used as:

<Dropdown>
  <DropdownTrigger />
  <DropdownList />
</Dropdown>

Where the Dropdown component just renders what's passed into the default slot, but then it also creates context, and child components interact with such context, so no possibility to fully test the whole behavior when testing them in isolation. Any suggestions?

@JohnnyFun
Copy link
Contributor

Would svelte:component be what you're looking for? https://svelte.dev/docs#svelte_component

Can pass a comonent type in and render and instance of it.

@alejandroiglesias
Copy link
Author

@JohnnyFun how do you pass a svelte:component to the mount function?

@JohnnyFun
Copy link
Contributor

Oh sorry, I misunderstood what you were asking. The way I've been doing it is by wrapping the component(s) I want to test in a wrapper components with some example usages. Then I simply mount that wrapper component instead of the underlying component. I put my "wrapper" components in "./cypress/fixtures/components".

Something like this:

<h3>Simple example</h3>
<MyListComponent {items} let:item dataTest="simple-example">
   <strong>{item.name}</strong>
   <em>{item.desc}</em>
</MyListComponent>

<h3>Some other example</h3>
<MyListComponent {items} let:item dataTest="other-example">
   ...
</MyListComponent>

<script>
   export let items
</script>

@JohnnyFun
Copy link
Contributor

Makes it really nice when building up a component too. Kind of like an interactive style guide that shows how to use your components and what the expected behavior of them is.

@alejandroiglesias
Copy link
Author

I see what you mean. I ended up doing that in some cases since the team already has wrapper components for rendering in Storybook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants