bahmutov / cypress-svelte-unit-test

Unit testing Svelte components in Cypress E2E test runner
162 stars 21 forks source link

`onDestroy` not called between tests or between mount() calls #252

Open OlsonDev opened 3 years ago

OlsonDev commented 3 years ago

Is this a bug report or a feature request?

A little of both

If this is a new feature request, please describe it below

We have a use:action which wraps the focus-trap library. Without going into irrelevant details, that library maintains an internal state. Our action deactivates the focus-trap in its destroy(), cleaning up focus-trap's internal state. This works perfect in our app. However, it does not work at all in component tests because onDestroy is never called between tests or when the mounted component is removed from the DOM.

We tried to work around it with something like:

mount(MyComponent, options).then(component => {
    // Assert some things
    component.$destroy()
})

but it didn't seem to work. Double-checked and $destroy() doesn't return a promise or anything we need to await either. Also, oddly, sometimes component.$destroy doesn't seem to exist. 🤔

We've run into this issue in other ways, where our app works fine (and the components work fine under E2E tests), but component tests don't. For example, we add event listeners on document when a component is mounted, but then we remove them when the component is onDestroy()'d. Even though we only have one mount call per it() in Cypress, those event listeners still stick around because Cypress isn't creating a new document between tests (possibly for performance?) -- and so the next test runs are affected by the previous test(s).

It would be nice if this library just handled that for every mount call. I'm not exactly sure how you'd do that, but I suspect this code is the culprit that'd need to change:

    if (el) {
      while (el.firstChild) {
        el.removeChild(el.firstChild)
      }
    }