debugger: Fix a few issues with JS debugging (#32918)

Cole Miller created

- Don't assume all located tasks come from our test runnables
- Run tests from the right working directory
- Scope forking behavior customization for jest and vitest more tightly,
to just our test runnables
- Standardize on `$PACKAGE_MANAGER exec -- $TEST_LIBRARY ...` to fix
runnables not working with npm

Release Notes:

- Debugger Beta: Fixed issues with debugging tasks from package.json and
test runnables.

Change summary

crates/languages/src/typescript.rs           | 61 +++++++++++++++------
crates/project/src/debugger/locators/node.rs | 32 +----------
2 files changed, 48 insertions(+), 45 deletions(-)

Detailed changes

crates/languages/src/typescript.rs 🔗

@@ -164,28 +164,37 @@ impl PackageJsonData {
             task_templates.0.push(TaskTemplate {
                 label: "jest file test".to_owned(),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
-                args: vec!["jest".to_owned(), VariableName::Filename.template_value()],
-                cwd: Some(VariableName::Dirname.template_value()),
+                args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
+                    "jest".to_owned(),
+                    "--runInBand".to_owned(),
+                    VariableName::File.template_value(),
+                ],
+                cwd: Some(TYPESCRIPT_JEST_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
             task_templates.0.push(TaskTemplate {
                 label: format!("jest test {}", VariableName::Symbol.template_value()),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
                 args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
                     "jest".to_owned(),
+                    "--runInBand".to_owned(),
                     "--testNamePattern".to_owned(),
                     format!(
                         "\"{}\"",
                         TYPESCRIPT_JEST_TEST_NAME_VARIABLE.template_value()
                     ),
-                    VariableName::Filename.template_value(),
+                    VariableName::File.template_value(),
                 ],
                 tags: vec![
                     "ts-test".to_owned(),
                     "js-test".to_owned(),
                     "tsx-test".to_owned(),
                 ],
-                cwd: Some(VariableName::Dirname.template_value()),
+                cwd: Some(TYPESCRIPT_JEST_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
         }
@@ -195,11 +204,15 @@ impl PackageJsonData {
                 label: format!("{} file test", "vitest".to_owned()),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
                 args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
                     "vitest".to_owned(),
                     "run".to_owned(),
-                    VariableName::Filename.template_value(),
+                    "--poolOptions.forks.minForks=0".to_owned(),
+                    "--poolOptions.forks.maxForks=1".to_owned(),
+                    VariableName::File.template_value(),
                 ],
-                cwd: Some(VariableName::Dirname.template_value()),
+                cwd: Some(TYPESCRIPT_VITEST_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
             task_templates.0.push(TaskTemplate {
@@ -210,21 +223,25 @@ impl PackageJsonData {
                 ),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
                 args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
                     "vitest".to_owned(),
                     "run".to_owned(),
+                    "--poolOptions.forks.minForks=0".to_owned(),
+                    "--poolOptions.forks.maxForks=1".to_owned(),
                     "--testNamePattern".to_owned(),
                     format!(
                         "\"{}\"",
                         TYPESCRIPT_VITEST_TEST_NAME_VARIABLE.template_value()
                     ),
-                    VariableName::Filename.template_value(),
+                    VariableName::File.template_value(),
                 ],
                 tags: vec![
                     "ts-test".to_owned(),
                     "js-test".to_owned(),
                     "tsx-test".to_owned(),
                 ],
-                cwd: Some(VariableName::Dirname.template_value()),
+                cwd: Some(TYPESCRIPT_VITEST_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
         }
@@ -233,8 +250,13 @@ impl PackageJsonData {
             task_templates.0.push(TaskTemplate {
                 label: format!("{} file test", "mocha".to_owned()),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
-                args: vec!["mocha".to_owned(), VariableName::Filename.template_value()],
-                cwd: Some(VariableName::Dirname.template_value()),
+                args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
+                    "mocha".to_owned(),
+                    VariableName::File.template_value(),
+                ],
+                cwd: Some(TYPESCRIPT_MOCHA_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
             task_templates.0.push(TaskTemplate {
@@ -245,17 +267,19 @@ impl PackageJsonData {
                 ),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
                 args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
                     "mocha".to_owned(),
                     "--grep".to_owned(),
                     format!("\"{}\"", VariableName::Symbol.template_value()),
-                    VariableName::Filename.template_value(),
+                    VariableName::File.template_value(),
                 ],
                 tags: vec![
                     "ts-test".to_owned(),
                     "js-test".to_owned(),
                     "tsx-test".to_owned(),
                 ],
-                cwd: Some(VariableName::Dirname.template_value()),
+                cwd: Some(TYPESCRIPT_MOCHA_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
         }
@@ -265,10 +289,12 @@ impl PackageJsonData {
                 label: format!("{} file test", "jasmine".to_owned()),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
                 args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
                     "jasmine".to_owned(),
-                    VariableName::Filename.template_value(),
+                    VariableName::File.template_value(),
                 ],
-                cwd: Some(VariableName::Dirname.template_value()),
+                cwd: Some(TYPESCRIPT_JASMINE_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
             task_templates.0.push(TaskTemplate {
@@ -279,17 +305,18 @@ impl PackageJsonData {
                 ),
                 command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
                 args: vec![
+                    "exec".to_owned(),
+                    "--".to_owned(),
                     "jasmine".to_owned(),
                     format!("--filter={}", VariableName::Symbol.template_value()),
-                    VariableName::Filename.template_value(),
+                    VariableName::File.template_value(),
                 ],
                 tags: vec![
                     "ts-test".to_owned(),
                     "js-test".to_owned(),
                     "tsx-test".to_owned(),
-                    "jasmine-test".to_owned(),
                 ],
-                cwd: Some(VariableName::Dirname.template_value()),
+                cwd: Some(TYPESCRIPT_JASMINE_PACKAGE_PATH_VARIABLE.template_value()),
                 ..TaskTemplate::default()
             });
         }

crates/project/src/debugger/locators/node.rs 🔗

@@ -1,4 +1,4 @@
-use std::{borrow::Cow, path::PathBuf};
+use std::borrow::Cow;
 
 use anyhow::{Result, bail};
 use async_trait::async_trait;
@@ -31,38 +31,14 @@ impl DapLocator for NodeLocator {
         if build_config.command != TYPESCRIPT_RUNNER_VARIABLE.template_value() {
             return None;
         }
-        let test_library = build_config.args.first()?;
-        let program_path_base: PathBuf = match test_library.as_str() {
-            "jest" => "${ZED_CUSTOM_TYPESCRIPT_JEST_PACKAGE_PATH}".to_owned(),
-            "mocha" => "${ZED_CUSTOM_TYPESCRIPT_MOCHA_PACKAGE_PATH}".to_owned(),
-            "vitest" => "${ZED_CUSTOM_TYPESCRIPT_VITEST_PACKAGE_PATH}".to_owned(),
-            "jasmine" => "${ZED_CUSTOM_TYPESCRIPT_JASMINE_PACKAGE_PATH}".to_owned(),
-            _ => VariableName::WorktreeRoot.template_value(),
-        }
-        .into();
-
-        let program_path = program_path_base
-            .join("node_modules")
-            .join(".bin")
-            .join(test_library);
-
-        let mut args = if test_library == "jest" {
-            vec!["--runInBand".to_owned()]
-        } else {
-            vec![]
-        };
-        args.extend(build_config.args[1..].iter().cloned());
 
         let config = serde_json::json!({
             "request": "launch",
             "type": "pwa-node",
-            "runtimeExecutable": program_path,
-            "args": args,
+            "args": build_config.args.clone(),
             "cwd": build_config.cwd.clone(),
-            "env": {
-                "VITEST_MIN_FORKS": "0",
-                "VITEST_MAX_FORKS": "1"
-            },
+            "runtimeExecutable": build_config.command.clone(),
+            "env": build_config.env.clone(),
             "runtimeArgs": ["--inspect-brk"],
             "console": "integratedTerminal",
         });