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

Monorepo instructions are unclear, samples not working #81

Open
hidde-jan opened this issue Sep 6, 2022 · 27 comments
Open

Monorepo instructions are unclear, samples not working #81

hidde-jan opened this issue Sep 6, 2022 · 27 comments
Labels
feat: workspace p2-nice-to-have Not breaking anything but nice to have (priority)

Comments

@hidde-jan
Copy link

Describe the bug
Currently, there is (some) support for monorepos, but how to actually get extension working for monorepos is unclear.

The monorepo examples in /samples don't work out of the box as well.

To Reproduce
Steps to reproduce the behavior on the example project:

  1. Clone this repository
  2. Open samples/monorepo in vscode
  3. Install the extension
  4. Run pnpm install
  5. Run all tests from the extension

Expected behavior
The tests should run successfully.

Screenshots
If applicable, add screenshots to help explain your problem.
Screenshot 2022-09-06 at 16 45 43

Environment

(Paste info.txt content generated by the example project)

{
  "System": {
    "OS": "macOS 12.3.1"
  },
  "Binaries": {
    "Node": {
      "version": "16.14.0",
      "path": "~/.nodenv/versions/16.14.0/bin/node"
    },
    "Yarn": {
      "version": "1.22.15",
      "path": "~/.nodenv/versions/16.14.0/bin/yarn"
    },
    "npm": {
      "version": "8.3.1",
      "path": "~/.nodenv/versions/16.14.0/bin/npm"
    }
  },
  "IDEs": {
    "VSCode": {
      "version": "1.70.2",
      "path": "/opt/homebrew/bin/code"
    }
  },
  "npmPackages": {
    "vite": {
      "installed": "2.9.15",
      "wanted": "^2.9.9"
    },
    "vitest": {
      "installed": "0.12.10",
      "wanted": "^0.12.6"
    }
  }
}

Additional context
Add any other context about the problem here.

@hidde-jan hidde-jan added the p3-minor-bug An edge case that only affects very specific usage (priority) label Sep 6, 2022
@hidde-jan hidde-jan changed the title Monorepo instruction are unclear Monorepo instructions are unclear, samples not working Sep 6, 2022
@Ragura
Copy link

Ragura commented Sep 15, 2022

I'm getting the same errors in my own mono repo when using the extension. I can see the tests, but not run them (get the same "Test result not found" message). I'm also on macOS using M1 processor.

Trying to debug with a launch.json file and setting the program folder to the correct node_modules folder with vitest.mjc in it and launching the test file in debug mode also doesn't work and prompts me to install vite because it is not installed.
The launch.json file includes the following:

{
      "type": "node",
      "request": "launch",
      "name": "Debug Current Test File",
      "autoAttachChildProcesses": true,
      "skipFiles": [
        "<node_internals>/**",
        "**/node_modules/**"
      ],
      "program": "${workspaceFolder}/apps/my_app/node_modules/vitest/vitest.mjs",
      "args": [
        "run",
        "${relativeFile}"
      ],
      "smartStep": true,
      "console": "integratedTerminal"
    }

I am aware that doesn't directly relate to the extension, but it might be useful info?

@medihack
Copy link

Same problem here also with a monorepo setup (using Gitpod, but shouldn't matter). I also get the error message "Test result not found.". Any workarounds yet?

@ghost91-
Copy link

Having the same issue :/

@rosskevin
Copy link

I have the same issue with the latest release including the fix for #55. I'm not clear what the correct vitest.commandLine is for a monorepo as my top level script is:

"test": "lerna exec --stream --parallel -- yarn test"

and each package is:

"test": "vitest"

This means multiple vitest processes. Is there a different way to setup vitest so it is one process over the entire monorepo that would then work with this vscode plugin?

@rogerleung0411
Copy link

Sorry to bother you @zxch3n but, any workaround for this monorepo issue? Or can u provide some information about this, im glad to create a pr if i can :)

@jherdman
Copy link

jherdman commented Nov 4, 2022

Here's my scenario and workaround.

I have a monorepo that, so far, only uses Vitest in one of the projects. I configured this extension to run the tests as follows:

pnpm --filter MY_PACKAGE_NAME test --

@codethief
Copy link

codethief commented Dec 12, 2022

I've also been struggling to run my tests which, together, with vite.config.ts are located in a subfolder of my repo / workspace. The only thing that seems to work (somewhat) is setting the following in the VSCode workspace settings:

    "vitest.commandLine": "npx vitest --run --config mysubfolder/vite.config.ts",
    "vitest.include": [
      "**/mysubfolder/**/*.test.ts"
    ],

or (more or less equivalently)

    "vitest.commandLine": "npm run test",
    "vitest.include": [
      "**/mysubfolder/**/*.test.ts"
    ],

where the test command is defined in the package.json as:

  "test": "cd mysubfolder && vitest --run --config vite.config.ts",

Anyway, in both cases vitest then still reports "Test result not found […]" for every single test, even though the verbose test logs do report the test results, e.g.:

Test result not found. 
Are there tests with the same name?
Can you run vitest successfully on this file? Does it need custom option to run?

Vitest output:

 RUN  v0.25.1 /home/user/myrepo/mysubfolder
      API started at http://localhost:37661

 ❯ src/components/MyComponent/__tests__/MyComponent.test.ts  (11 tests | 1 failed | 10 skipped) 145ms
   ❯ src/components/MyComponent/__tests__/MyComponent.test.ts > MyComponent > shows error page on failed request
     → Unable to find an element by: [data-testid="generic-error-overlay"]

…

(DOM)

…

(stack trace)

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

 Test Files  1 failed (1)
      Tests  1 failed | 10 skipped (11)
   Start at  16:04:15
   Duration  3.75s (transform 2.25s, setup 122ms, collect 2.18s, tests 145ms)

What gives?

@divmgl
Copy link

divmgl commented Dec 18, 2022

I'm able to get some integration working with this with a monorepo but not quite. In my root package.json:

"test:app": "pnpm --filter app test --",

And then in my VSCode configuration:

"vitest.commandLine": "pnpm test:app",

But I'm getting that all of the tests are skipped:


[INFO 10:57:58 PM]  ↓ src/pages/CreateEditProjectPage/FirstPage.test.tsx  (1 test | 1 skipped)



 Test Files  1 skipped (1)

      Tests  1 skipped (1)

   Start at  22:57:56

   Duration  2.16s (transform 650ms, setup 153ms, collect 1.31s, tests 0ms)

Screenshot 2022-12-17 at 10 59 24 PM

Here's what Vitest runs according to Visual Studio:

> vitest "/Users/user/dev/monorepo/packages/app/src/pages/CreateEditProjectPage/FirstPage.test.tsx" "-t" "FirstPage.name renders" "--api.port" "62517" "--api.host" "127.0.0.1"

@hidde-jan
Copy link
Author

@zxch3n could you or someone else from the team please have a look? Since there are examples for monorepos, and you created those, I think you are probably the most suitable person to answer the questions in this issue.

@dohooo
Copy link

dohooo commented Dec 28, 2022

Same here.


I have debugged it and found some information.

First, I have two test files in the single and multi repo.

single

// samples/basic/test/add.test.ts

import { describe, expect, it } from 'vitest'

describe('single testing', () => {
  it('1', () => {
    expect(1).toBe(1)
  })
  it('2', () => {
    expect(2).toBe(2)
  })
})

multi

// samples/monorepo/packages/react/test/basic.test.tsx

import { describe, expect, it } from 'vitest'

describe('multi testing', () => {
  it('1', () => {
    expect(1).toBe(1)
  })
  it('2', () => {
    expect(2).toBe(2)
  })
})

There was some difference between them when I added the breakpoint in the handler event.

This file is used to receive testing information from the vitest server.

image

  • Running the test of "single repo".

image

  • Running the test of "multi repo".

image

I don't know why the tasks list is empty when running it in the multi repo and the "Test result not found" error comes from here:
image

So the finishedTests is empty if tasks are empty, and then we'll get this error message. This problem may come from vitest because it sends events incorrectly.

And I found another problem in the vitest. The testing result fails when I run it via vitest <specific file>, like:

// ✅
npm vitest 

image

// ✅
npm vitest 

image

Is that mean I must run this command( vitest ) in the sub-package directory, or have I lost some arguments? This repo's underlying logic is run the command line in the node, so maybe this problem causes this issue. @zxch3n

@sheremet-va sheremet-va added p2-nice-to-have Not breaking anything but nice to have (priority) and removed p3-minor-bug An edge case that only affects very specific usage (priority) labels Mar 15, 2024
@sheremet-va
Copy link
Member

Would be very nice to have a similar guide on how to use the extension that Jest extension has - with images and examples.

@vikingair
Copy link

I finally found a proper workaround for something that should definitely be integrated into the plugin itself.

Create file .vscode/vitest-fix.mjs

import fs from "fs";
import path from "path";
import { execSync } from "child_process";

const [testFile, ...args] = process.argv.slice(2);

const findClosestPackage = (p) => {
    const parent = path.dirname(p);
    if (fs.existsSync(path.join(parent, "package.json"))) return parent;
    return findClosestPackage(parent);
}

const cwd = findClosestPackage(testFile);

const targetPath = path.relative(cwd, testFile);

execSync(`pnpm vitest -w ${targetPath} ${args.map((a) => a.startsWith("-") ? a : `"${a}"`).join(" ")}`, { env: { ...process.env }, cwd, stdio: "inherit" });

And add this to your .vscode/settings.json

"vitest.commandLine": "node .vscode/vitest-fix.mjs",

What it does? It consumes all passed args and then runs vitest in watch mode with the passed args, but

  • Using the current package (with closest package.json) as workdir
  • Changing the first passed path param

@sheremet-va
Copy link
Member

I finally found a proper workaround for something that should definitely be integrated into the plugin itself.

Please, use the latest pre-release version.

And add this to your .vscode/settings.json

The latest version doesn't support vitest.commandLine option.

@vikingair
Copy link

@sheremet-va Then lets hope the pre-release also fixes finally that issue with these workspaces, where I have to manually do things that could have been just inferred correctly by searching for the closest vite(st) config :/

@sheremet-va
Copy link
Member

@sheremet-va Then lets hope the pre-release also fixes finally that issue with these workspaces, where I have to manually do things that could have been just inferred correctly by searching for the closest vite(st) config :/

There is no need to "hope", you can install it yourself and see if it fixes it for you.

@weyert
Copy link

weyert commented Apr 29, 2024

If I understand it correctly the extension has a hard-requirement that you install vitest in the root workspace otherwise it is not working.

I think it would be nice if it would use the vitest from the package with vitest.config.ts-file instead. I haven't figured out how to achieve that.

Also seems to display all workspaces (using pnpm) which don't have a vitest.config.*-file, such as projects that only have a jest.config.*-file instead or no file at all. I think it shows all places where it finds *.test* or *.spec*-files.

@sheremet-va
Copy link
Member

sheremet-va commented Apr 29, 2024

If I understand it correctly the extension has a hard-requirement that you install vitest in the root workspace otherwise it is not working.

There is no such requirement, it uses the working directory of a config file.

Also seems to display all workspaces (using pnpm) which don't have a vitest.config.*-file, such as projects that only have a jest.config.*-file instead or no file at all. I think it shows all places where it finds *.test* or *.spec*-files.

It only shows tests that Vitest found with provided config.

@mrmckeb
Copy link

mrmckeb commented Oct 9, 2024

We're also have trouble setting this up. I can provide a full reproduction if that would help?

In short, we have:

apps/*/vitest.[config|projects].ts
packages/*/vitest.config.ts

The reason we have the nested vitest.projects.ts is because the app has unit tests, JSDOM tests, and browser-mode tests running alongside each other.

Only the first app shows up (containing a vitest.workspace.ts file). Everything works as expected within that app though.

If I do add a vitest.workspace.json file to the workspace itself (the project root), it then fails with:

Vitest not found in "[folder-name]" folder. Please run npm i --save-dev vitest to install Vitest.

Perhaps the issue for us is the that extension doesn't recognise non-workspace level vitest.[projects|workspace].ts files?

I'm happy to help out with this issue too.

@sheremet-va
Copy link
Member

sheremet-va commented Oct 9, 2024

I can provide a full reproduction if that would help?

Please, do. The extension prioritizes workspace configs, and should always start a separate Vitest process for every config.

It will ignore non-workspace Vitest configs if there is at least one workspace config.

@mrmckeb
Copy link

mrmckeb commented Oct 9, 2024

Hi @sheremet-va, I think that's the issue we're hitting.

It will ignore non-workspace Vitest configs if there is at least one workspace config.

Here's a minimal repro, showing how we have this set up:
https://github.com/mrmckeb/vitest-vscode-repro

@sheremet-va
Copy link
Member

sheremet-va commented Oct 9, 2024

I think that's the issue we're hitting.

Then, it is expected. The extension priorities are:

  1. Vitest workspace files
  2. Vitest config files
  3. package.json scripts commands starting with vitest

If the extension finds one, it ignores the others.

@mrmckeb
Copy link

mrmckeb commented Oct 9, 2024

What changes could we make to this to support the extension better?

We don't really want to have a repo-root vitest.workspace.ts file, as we use task caching (via Turborepo) which is designed to have scripts run within packages, not from the workspace.

Perhaps the extension could differentiate between "projects" and "workspace", where vitest.projects.ts is for use within monorepo packages with multiple projects?

I'm happy to contribute to Vitest to help improve this.

@sheremet-va
Copy link
Member

sheremet-va commented Oct 9, 2024

What changes could we make to this to support the extension better?

I don't know what would be the best way to do that, honestly. Technically, we can initiate all workspaces first, then glob all config files and filter out those that are part of the workspace, maybe? And the rest can be initiated as separate processes.

It's quite hard to "guess" what the user expectation is based on the file system structure. I am open to any ideas (just in a sentence form is fine, not necessarily an implementation).

The recommended way right now is to have a single workspace file because it will keep just one child_process instead of spawning vitest for every config.

@mrmckeb
Copy link

mrmckeb commented Oct 9, 2024

From my perspective, it feels like the workspace.config.ts files are meant to be at the workspace root (which is often the repo root), and not within packages. But I also feel that our usecase is legitimate and fits into what a workspace is.

Your idea seems like it would work, and be a simple, non-breaking change.

Another approach might be to make a breaking change:

  • At the package level, users can have a single vitest.config.ts, or a vitest.projects.ts if they want to define multiple projects (via defineProjects which could just alias defineWorkspace for now).
  • Users that want to run Vitest from the workspace can use vitest.workspace.ts, but this would expect vitest to also be installed at the workspace level.

In that case, the extension could prioritise vitest.workspace.ts if it exists - and is still assumed to be at the workspace/root level. If vitest.projects.ts exists, it has the highest priority within the package it lives in, but not the entire workspace.

@sheremet-va
Copy link
Member

sheremet-va commented Oct 9, 2024

The thing is that we don't want to encourage people to have a lot of configs in separate places. There is even a warning if you have more than three configs. Allowing mixing workspaces and configs contradicts this.

The extension spawns a new process for every config and keeps it running in the background to achieve very fast feedback when you press the "run test" button. Keeping a lot of processes is not very memory and CPU efficient, so I would rather focus on improving the single vitest.workspace experience (maybe allow merging with other workspaces?). Vitest itself has a separate file just for vscode: https://github.com/vitest-dev/vitest/blob/main/vitest.workspace.vscode.ts

@mrmckeb
Copy link

mrmckeb commented Oct 10, 2024

My team could use the approach you've used above (vitest.workspace.vscode.ts) too, but I was hoping to find a solution that doesn't require users to add extension-specific config - and that approach requires installing vitest to the root of the repository/workspace.

I do understand the performance concern though. A monorepo could theoretically have multiple version of Vitest in use, which could add to the confusion.

Perhaps the extension could be changed to only keep alive processes for files that are open?

@sheremet-va
Copy link
Member

sheremet-va commented Oct 10, 2024

Perhaps the extension could be changed to only keep alive processes for files that are open?

This might actually be relatively easy to implement, but we will still need to start the process and close it at least once to get all test files (Vitest is the one resolving all the configs and workspaces, not the extension).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: workspace p2-nice-to-have Not breaking anything but nice to have (priority)
Projects
None yet
Development

No branches or pull requests