-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Tests are failing after updating to Vite 4.1.0 #2834
Comments
Hello @yuliankarapetkov. Please provide a minimal reproduction using a GitHub repository or StackBlitz. Issues marked with |
Hey @sheremet-va, I just updated my comment with a StackBlitz example, along with some further explanation and config. Hope that gives a bit more context of the issue. |
Test passes with following: <script lang="ts">
- import { onMount } from "svelte"
+ import { onMount } from "svelte/internal"
Maybe related to sveltejs/svelte#5534? |
Vitest should still work with import from |
@sheremet-va, nice catch! How did you find that? I can confirm that this was the cause of my bug since after changing all |
Started to rollback local It seems that entrypoint for Svelte is resolved to
Parameters used here below: https://github.com/vitejs/vite/blob/d953536aae448e2bea0f3a7cb3c0062b16d45597/packages/vite/src/node/plugins/resolve.ts#L1108-L1112
Svelte's entrypoints: https://github.com/sveltejs/svelte/blob/82d2982845df188631993db6b18c2842e3613acf/package.json#L23-L87 It does make sense that Another work-around for projects for now so that test code does not need changes: import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
alias: [
{
find: /svelte\/ssr.mjs/,
replacement: "svelte/index.mjs",
},
], |
I think Svelte team wants Vitest to use browser condition (resolve.conditions in config) here. The problem is that other packages will not work with it, if we enable it by default (one of the most popular things to do with jest and jsdom right now is adding node condition overriding default browser one, because package authors don’t expect this code to run inside a node with emulated browser environment). |
Just wanna leave a hack here that worked for us, without having to change all the imports. Create or add this to your test setup file import * as svelteinternal from 'svelte/internal';
import { vi } from 'vitest';
beforeAll(() => {
vi.mock('svelte', () => svelteinternal);
}); |
Using
I guess the |
Yeah the Vite PR change is intentional as it was previously incorrect (though many tooling relied on it). If setting (Though usually I prefer testing UI components with a real/headless browser) |
For now I recommend using a workaround with This is much deeper problem than Svelte issue. Vitest processes This creates an issue, if code is imported from the same package in two different modes, - especially if code depends on a singleton. Currently to bypass this Vitest hardcodes One of the reason why Vitest doesn't process everything with web mode is performance - Vite is (at least, was) really slow to transform a single ts/js file. The other issue is that library authors also expect browser condition to be run in a browser, so they don't follow node ESM spec (file in |
I'm facing a similar issue and would be interested to know if the mentioned Would you mind expanding a little bit on what should be done to implement said workaround? |
Add "browser" to your |
If I set resolve: {
conditions: [
...process.env.VITEST ? ['browser'] : []
]
} I get another error multiple times, when running the unit tests
|
Yes, {
"browser": {
"import": "./path.mjs"
"require": "./path.cjs"
}
} But this doesn't really make sense for library authors, because "browser" condition should be executed in the browser, and it doesn't support "require". This is a very complicated issue, and I hope we can discuss it with the Vite team when we start moving vite-node into Vite core. Right now you can use hardcoded aliases for this instead of browser condition (but some svelte libraries might not work!): export default defineConfig({
test: {
alias: {
svelte: "svelte/internal"
}
}
}) As you can see, the state of ESM/CJS is a mess 😄 |
setting the To make sure the browser condition is added in the front and you don't modify conditions when vitest is not active, use a plugin with config hook: // ...
const vitestBrowserConditionPlugin = {
name: 'vite-plugin-vitest-browser-condition',
config({resolve}) {
if(process.env.VITEST) {
resolve.conditions.unshift('browser');
}
}
}
export default defineConfig({
// ...
plugins: [vitestBrowserConditionPlugin,svelte()]
}) |
Unfortunately that won't help with @vekunz case, openid-client depends on jose and jose package.json has an interesting exports map. for deno and bun they expose the same export as for browser, but for generic import/require, they export a node specific file. so with adding the browser condition you're changing what gets imported from jose and that doesn't work inside node. oops. |
I think they have somewhat correct exports map. They don't expect their code to be imported with I think the problem comes from what developers consider a "browser" condition. Should it be used, when "browser-like" environment is initiated (code has access to global "window" and "document" for example), or when the environment itself is a browser (meaning, the code will be processed by build tools)? I think most people consider it to be the second one, and that's why I am hesitant to add this condition in Vitest by default. For me, the biggest issue is that |
Agree that what jose does works in regular environments and usecases, still interesting that bun/deno get the browser file via their own conditions whereas node gets a node file via "import"/"require". The trick with alias above is a more targeted way to ensure svelte is resolved to what it exports for browsers, so in situations where there are competing needs it can be a workaround, though this might become a problem if svelte decided to change its exports structure in a future major release (you'll know from the release notes and your tests crashing so not too bad) |
Unfortunately, this does not work for me. If I set this configuration, a get a new error:
|
I guess it needs to be: export default defineConfig({
test: {
alias: [
{ find: /^svelte$/, replacement: "svelte/internal" }
]
}
}) to be more accurate. |
* fix scroll to active ToC li aborting scroll from within-page links * readme document new prop scrollBehavior: 'auto' | 'smooth' = `smooth` * fix tests from vitest broken svelte/internal module resolution vitest-dev/vitest#2834 * clean up
Note that vite 4.1+ requires browser condition to run onMount() in svelte components properly during tests vitest-dev/vitest#2834 (comment)
Any news on this issue? |
This should be fixed in the latest version. If you still have problems, considered enabling |
@sheremet-va it still has an issue. experimentalOptimizer doesn't help |
It works. Thank you! |
The issue is indeed still there. The workaround works for me. Not sure if this is helpful, but to reproduce the issue with the project that I'm working o:
So, for some reason, the Svelte component with these contents is not rendered during the test. All tests pass with the |
Just chipping in that this issue is still present as of vitest 0.34.6. |
Another option would be to add import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [sveltekit()],
// see https://github.com/testing-library/svelte-testing-library/issues/222
resolve: {
...(process.env.VITEST
? {
conditions: ['browser', 'import', 'module', 'default']
}
: null),
},
}); So far, in my project with a simple setup, it works regardless of the conditions order, as long as browser is added to the list. |
@sibiraj-s thanks for sharing. I tried your workaround but that doesn't work in my case (the alias workaround works fine though). |
Oh, Not sure about the reason, but here is the link for the code that I used. https://github.com/sibiraj-s/svelte-tiptap/blob/3cc167aa67aeb3af1bcd74bbaa68d6011b1d6324/vite.config.ts#L8 |
Configure @testing-library/jest-dom correctly to resolve the type definitions in the test files, even the plugin is extended in a global setup file. The Svelte component's onMount hooks right now executed properly. Unfortunately vitest running in node but Svelte render's the components in SSR mode, so the onMount callbacks didn't executed in tests. An ugly workaround was needed to solve this: vitest-dev/vitest#2834 (comment)
Describe the bug
I'm using SvelteKit with Vitest. I updated SvelteKit and Vitest to their latest versions - 1.5.0 and 0.28.4 respectfully. However, updating Vite from 4.0.4 to 4.1.0 caused 15% of my tests to fail (60/400).
Most of the errors seem unreasonable. For example, removing a DOM element throws a
Failed to execute removeChild on Node
error. OrFound multiple elements with the text: ...
where there's just a single element containing that exact copy;Error: Unable to fire a "click" event - please provide a DOM element.
,Error: unable to find element with text
, etc.Reproduction
Here's a simple StackBlitz example.
npm run test
Then do the following:
package.json
vite
from4.1.0
to4.0.4
npm run test
The example explained
It's a simple component with an if statement:
Test file:
Result with Vite 4.1.0:
This is just a single example but similar issues occur where there's some sort of an asynchronous code used (or conditionals), like promises,
setTimeout
,useFakeTimers()
andadvanceTimersByTime()
, TestingLIbrary'swaitFor()
function, etc.More dependencies & config
See StackBlitz example for more info
package.json
vite.config.ts
setupTest.js
System Info
Used Package Manager
npm
Validations
The text was updated successfully, but these errors were encountered: