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

findComponent() is not ideal for testing microfrontends #1759

Closed
ulissesferreira opened this issue Jan 5, 2021 · 4 comments
Closed

findComponent() is not ideal for testing microfrontends #1759

ulissesferreira opened this issue Jan 5, 2021 · 4 comments

Comments

@ulissesferreira
Copy link

Subject of the issue

Hello all and thanks for the open source work you do 👋. I am currently developing an application using microfrontends with the framework single-spa. A general architecture overview looks somewhat like this:

  • Main app (Major) is responsible for auth, loading dependencies, routing and the index.html layout
  • Smaller apps (microapps) make up each route and are loaded inside a specific div

Now each one of those apps is a separate repository and a separate Vue application. Each one has their own set of tests and it only outputs a final javascript bundle that gets loaded by the Main app.

When developing tests for these smaller apps we make use of components from our component library and other components from the Major app.

We import them like so

import { ComponentA } from '@unbabel/major'; import { ComponentB } from '@unbabel/ui';

These components do not exist on the local app because they are avaliable in the Main app. @unbabel/major is also not an npm package (contrary to @unbabel/ui).

What does this mean?

Imagine you are testing a component from one of those microapps. You will not be able to mount your component without some of the child components being stubs because Vue Test Utils has no idea on where to get them. Using the above example, Vue Test Utils will not be able to mount ComponentA because for the microapp @unbabel/major does not exist.

So whenever you want to find this component in your tests you won't be able to use:

findComponent( ComponentA )

you also won't be able to use

findComponent ({ name: ComponentA_Name })

this leaves us with

findComponent ({ ref: ComponentA_Ref })

However this will mean some of the previous components that didn't need refs to be found now need them (previously we could use find with data-testid)

What should be the approach in this situations?

I am more than happy to jump on a call and talk about the issue more in depth 😁

Steps to reproduce

  1. Create a simple single-spa multi-application setup.
  2. Develop an example component on the Main application of the microfrontend repository you just created
  3. Try to test attributes being passed to that component in one of the children applications

Expected behaviour

Maybe there should be a different way to find components? Maybe not deprecating the querySelector syntax?

Actual behaviour

You will need to add refs to a lot of components to find them

Possible Solution

n/a

@lmiller1990
Copy link
Member

Regarding "... ComponentA because for the microapp @unbabel/major does not exist ... so you cannot find it ...". Are you using Jest? Could you just mock it, and the find the mock? Eg:

jest.mock('@unbabel/major', () => ({ 
  return { 
    ComponentA: { name: 'ComponentA' }
  }
}))

wrapper.findComponent({ name: 'ComponentA' })

Just a shot in the dark, no idea if this would work.

If you want to use the the querySelector syntax, you can, just use find. Unless I am missing something.

@ulissesferreira
Copy link
Author

Hmmm ideally using the find would be perfect but there is currently a warning on the documentation that announces deprecation. Is that a mistake / outdated?

I never tried mocking it that way but also sounds like a fair approach

@lmiller1990
Copy link
Member

lmiller1990 commented Jan 12, 2021

I think the deprecation message is not ideal. What is deprecated is find(Foo), where the argument is a component. find('#query-selector') should be working fine.

Edit: found some more context on this in the original discussion. There are some unsolvable edge cases related to Vue 3 + VTU v2, which led to restricting findComponent to components (thus the name). Technically you can do findComponent('#foo') in here, but it won't work in the next version of Vue and Test Utils.

Historically with Vue 2 and VTU v1, people would do find(Comp).find('#foo'). This is not forward compatible with Vue 3 + VTU v2.

Since this is going to be a breaking change, we introduced it here for V1, so users would not be continuing with a to-be-broken API. By making find and findComponent not work together, it ensures test suites are more forward compatible.

I think either 1) mocking or 2) using a DOM selector is more ideal - using findComponent to find a component that literally does not exist in your project does not sound like something that should work. If you mock the component, you can find that (since it'll exist then). Can you give that a try?

@ulissesferreira
Copy link
Author

I think the above is the desired solution! Thank you for clearing this up and sorry for my late replies, I haven't been using Github in my day to work 🙏. Going to close the issue ✅

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

No branches or pull requests

3 participants