Skip to content

"browser" export condition is not set when testing with jsdom #7215

@rChaoz

Description

@rChaoz

Describe the bug

When testing SvelteKit code, various parts can depend on whether running in the browser like so:

if (browser) window.addEventListener(...)

where browser is defined using esm-env, which does it using conditional exports in package.json:

"exports": {
	...
	"./browser": {
		"browser": "./true.js",
		"development": "./false.js",
		"production": "./false.js",
		"default": "./browser-fallback.js"
	},
	...
}

Now, development is set, so unless browser is also set, it will always be false. I know you can set export conditions in Vite, but I haven't seen anything similar in Vitest. I'd expect it to be set when using a browser environment, probably using an option or similar.

Reproduction

Stackblitz: https://stackblitz.com/edit/sveltejs-kit-template-default-muke8nsy
Steps: Just wait for install and run vitest in console

Workaround

I found this way to mock it, it works for me but I believe the property is also used by SvelteKit's vite plugin, which won't see this change, so there's some edge cases in which it might not work:

vi.mock(import("esm-env"), async (importOriginal): Promise<typeof import("esm-env")> => {
    const module = await importOriginal()
    if (typeof window == "object")
        return {
            ...module,
            BROWSER: true,
        }
    else return module
})

Interestingly you cannot wrap the entire call in an if (typeof window == "object") as the mock somehow leaks into tests for which the check fails, this way it re-mocks it and removes the property for those.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions