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

Constructing a Request for a relative URL fails #4434

Closed
6 tasks done
micha149 opened this issue Nov 3, 2023 · 7 comments · Fixed by #4671
Closed
6 tasks done

Constructing a Request for a relative URL fails #4434

micha149 opened this issue Nov 3, 2023 · 7 comments · Fixed by #4671
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)

Comments

@micha149
Copy link

micha149 commented Nov 3, 2023

Describe the bug

I'm using vitest with happy-dom. In my application code I want to instanciate a Request from a relative URL like new Request('/api/foo'). From my perspective this should work and in my browser all works fine as expected. But creating the instance im my tests fails with:

TypeError: Invalid URL
 ❯ new URL node_modules/happy-dom/src/url/URL.ts:8:15
 ❯ Module.get src/data/api/common.ts:59:21
 ❯ src/data/api/common.test.ts:35:30

I digged a bit into the problem but can't really figure out whats going wrong. Something I noticed is that there is the Request constructor from node:internal instead of happy-dom when I print a stack trace from the URL constructor:

at new URL (file:///*******/node_modules/happy-dom/lib/url/URL.js:9:22)
at new _Request (node:internal/deps/undici/undici:5055:25)
at Module.get (/*******/src/data/api/common.ts:59:21)
at /*******/src/data/api/common.test.ts:35:30
at file:///*******/node_modules/@vitest/runner/dist/index.js:135:14
at file:///*******/node_modules/@vitest/runner/dist/index.js:58:26
at runTest (file:///*******/node_modules/@vitest/runner/dist/index.js:663:17)
at runSuite (file:///*******/node_modules/@vitest/runner/dist/index.js:782:15)
at runSuite (file:///*******/node_modules/@vitest/runner/dist/index.js:782:15)
at runSuite (file:///*******/node_modules/@vitest/runner/dist/index.js:782:15)

Switching to jsdom does not solve the issue. As well as creating a standalone script which uses happy-dom to create a Request works fine. So I think the problem lies in the integration into vitest.

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-8gdvjz?file=test%2Frequest.test.ts

System Info

System:
    OS: macOS 13.6.1
    CPU: (12) arm64 Apple M2 Max
    Memory: 14.14 GB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.9.0 - /opt/homebrew/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 10.1.0 - /opt/homebrew/bin/npm
    pnpm: 8.10.0 - /opt/homebrew/bin/pnpm
    bun: 1.0.7 - /opt/homebrew/bin/bun
    Watchman: 2023.10.23.00 - /opt/homebrew/bin/watchman
  Browsers:
    Brave Browser: 118.1.59.124
    Chrome: 116.0.5845.179
    Edge: 116.0.1938.69
    Safari: 17.1
  npmPackages:
    @vitejs/plugin-react-swc: 3.4.0 => 3.4.0
    vite: 4.5.0 => 4.5.0
    vitest: 0.34.6 => 0.34.6

Used Package Manager

npm

Validations

Copy link

stackblitz bot commented Nov 3, 2023

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@sheremet-va
Copy link
Member

This is just how node works:

> node
new Request('/api/foo')
// TypeError: Invalid URL

@sheremet-va sheremet-va closed this as not planned Won't fix, can't repro, duplicate, stale Nov 3, 2023
@micha149
Copy link
Author

micha149 commented Nov 3, 2023

Sure. But using a browser-like environment in my tests should behave as a browser, not like node?!

@sheremet-va
Copy link
Member

You don't use any environment in your reproduction. If you are using any environment, then Vitest doesn't control what variables are exposed and how they work.

@micha149
Copy link
Author

micha149 commented Nov 3, 2023

My bad. I updated the reproduction to represent more my setup. And btw using the following solves my current issue:

import { Request as HappyRequest } from 'happy-dom';

// @ts-expect-error This is only a temporary fix
global.Request = HappyRequest;

@sheremet-va sheremet-va reopened this Nov 3, 2023
@newlukai
Copy link

Currently I try to migrate from the cra stack to vite and vitest. The app I build relies on the browser's behavior to preceed a relative URL since this makes the app independent from a certain URL.

In contrast to @micha149 I'm using jsdom. There one can provide an own ResourceLoader. So I wrote one which just adds some scheme and host to a given relative URL.

Unfortunately, it seems that vitest serializes and deserializes the custom resource loader when passing that option to jsdom:

export default defineConfig({
    plugins: [
        react(),
        svgr()
    ],
    test: {
        setupFiles: ["src/setupTests.ts"],
        globals: true,
        environment: "jsdom",
        environmentOptions: {
            jsdom: {
                resources: new CustomResourceLoader()
            }
        }
    }
});

The next approach I try to follow is to create a custom environment.

@sheremet-va sheremet-va added bug p2-edge-case Bug, but has workaround or limited in scope (priority) and removed pending triage labels Nov 29, 2023
@sheremet-va
Copy link
Member

I fixed the issue with happy-dom, but jsdom doesn't support Request/Response, so I would recommend refactoring your code to something like this to support all environments:

new Request(new URL('/api/foo', import.meta.url))

@github-actions github-actions bot locked and limited conversation to collaborators Dec 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants