const { defineConfig } = require("@vscode/test-cli"); const fs = require("node:fs"); const path = require("node:path"); const fixturesPath = path.join(__dirname, "src/e2e-tests/fixtures/"); // The multi-root suites write workspace-level settings, which land in the // .code-workspace file itself. Those writes are part of what is under test and // cannot always be cleaned reliably, so each suite runs against a throwaway // gitignored copy of its committed workspace file, refreshed on every run. const generatedWorkspaceFile = (fixture, name) => { const generated = path.join( fixturesPath, fixture, `${name}.generated.code-workspace`, ); fs.copyFileSync( path.join(fixturesPath, fixture, `${name}.code-workspace`), generated, ); return generated; }; const multiRootWorkspaceFile = generatedWorkspaceFile( "multi-root-workspace", "multi-root", ); const multiRootPythonWorkspaceFile = generatedWorkspaceFile( "multi-root-python-workspace", "multi-root-python", ); // The Pkl extension is not published on the marketplace: Apple ships it as a // `.vsix` on GitHub releases, fetched by `node --run fetch-pkl-vsix`. When it // has not been fetched, the sdk-extensions suite skips its pkl tests instead // of failing, so the other suites of the label still run. const pklVsixDir = path.join(__dirname, ".vscode-test", "vsix"); const pklVsix = fs.existsSync(pklVsixDir) ? fs .readdirSync(pklVsixDir) .filter((file) => file.endsWith(".vsix")) .map((file) => path.join(pklVsixDir, file)) : []; // MISE_CEILING_PATHS stops mise from traversing above the fixtures directory, // so the workspaces under test never inherit this repository's own mise config. // Ceiling paths are exclusive: configs at the workspace root are still loaded. // MISE_LOCKED=0 overrides the CI-wide locked mode: the fixtures have no // lockfile, and locked mode would refuse to resolve their tools. module.exports = defineConfig([ { label: "default", files: "src/e2e-tests/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "task-execution-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", }, installExtensions: ["tombi-toml.tombi"], mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, { label: "tool-versions", files: "src/e2e-tests/tool-versions/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "tool-versions-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", // Pre-trust the fixture .tool-versions so tool resolution never // blocks on the trust dialog in CI. MISE_TRUSTED_CONFIG_PATHS: fixturesPath, }, mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, { label: "bootstrap", files: "src/e2e-tests/bootstrap/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "bootstrap-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, // Keep the machine's real global config (tools, bootstrap sections) // out of the tests so results match between dev machines and CI. MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "bootstrap-workspace", "global-config.toml", ), }, mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, { label: "broken-config", files: "src/e2e-tests/broken-config/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "broken-config-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "broken-config-workspace", "global-config.toml", ), }, mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, { label: "command-injection", files: "src/e2e-tests/command-injection/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "command-injection-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, }, mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, { label: "projects", files: "src/e2e-tests/projects/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "projects-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, // Keep the machine's own tracked configs and global config out of the // projects view so results match between dev machines and CI. MISE_STATE_DIR: path.join(fixturesPath, "projects-workspace", ".state"), MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "projects-workspace", "global-config.toml", ), }, mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, { label: "custom-extensions", files: "src/e2e-tests/custom-extensions/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "custom-extensions-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, // Keep the machine's real global config out of the tests, and keep the // tools installed by the suite out of the machine's mise data dir. MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "custom-extensions-workspace", "global-config.toml", ), MISE_DATA_DIR: path.join( fixturesPath, "custom-extensions-workspace", ".mise-data", ), MISE_CACHE_DIR: path.join( fixturesPath, "custom-extensions-workspace", ".mise-cache", ), }, // foxundermoon.shell-format is the target extension under test: its // `shellformat.path` setting is window-scoped, so the extension is // allowed to write it to the workspace settings. installExtensions: ["foxundermoon.shell-format"], mocha: { require: ["tsx/cjs"], timeout: 120_000, }, }, { label: "supported-extensions", files: "src/e2e-tests/supported-extensions/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "supported-extensions-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, // Keep the machine's real global config out of the tests, and keep the // tools installed by the suite out of the machine's mise data dir. MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "supported-extensions-workspace", "global-config.toml", ), MISE_DATA_DIR: path.join( fixturesPath, "supported-extensions-workspace", ".mise-data", ), MISE_CACHE_DIR: path.join( fixturesPath, "supported-extensions-workspace", ".mise-cache", ), }, // One marketplace extension per prebuilt-binary row of the // supported-extensions docs table. The NodeJS row targets the built-in // ms-vscode.js-debug, which needs no install. installExtensions: [ "ms-python.python", "denoland.vscode-deno", "oven.bun-vscode", "timonwong.shellcheck", "foxundermoon.shell-format", "signageos.signageos-vscode-sops", "exiasr.hadolint", "bufbuild.vscode-buf", "charliermarsh.ruff", "astral-sh.ty", "biomejs.biome", "sumneko.lua", "twxs.cmake", "ziglang.vscode-zig", "bazelbuild.vscode-bazel", ], mocha: { require: ["tsx/cjs"], // downloads over a dozen tools on a cold cache timeout: 600_000, }, }, { label: "sdk-extensions", files: "src/e2e-tests/sdk-extensions/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "sdk-extensions-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, // Keep the machine's real global config out of the tests, and keep the // SDKs installed by the suite out of the machine's mise data dir. MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "sdk-extensions-workspace", "global-config.toml", ), MISE_DATA_DIR: path.join( fixturesPath, "sdk-extensions-workspace", ".mise-data", ), MISE_CACHE_DIR: path.join( fixturesPath, "sdk-extensions-workspace", ".mise-cache", ), // tells the suite whether to assert the pkl rows or skip them MISE_E2E_PKL_VSIX: pklVsix.length ? "1" : "", }, // The java rows of the docs table: oracle.oracle-java plus the entries // sharing its code path. salesforce.salesforcedx-vscode-apex shares it // too but is left out, so its row stays unasserted. The pkl vsix is a // local file, not a marketplace id. installExtensions: [ "oracle.oracle-java", "redhat.java", "vscjava.vscode-gradle", "SonarSource.sonarlint-vscode", "ms-dotnettools.vscode-dotnet-runtime", ...pklVsix, ], mocha: { require: ["tsx/cjs"], // installs a JDK and the dotnet SDK on a cold cache timeout: 900_000, }, }, { label: "task-cache", files: "src/e2e-tests/task-cache/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "task-cache-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, // keep the task artifact cache and the source freshness state of the // suite inside the fixture, out of the machine's own mise directories MISE_CACHE_DIR: path.join( fixturesPath, "task-cache-workspace", ".mise-cache", ), MISE_STATE_DIR: path.join( fixturesPath, "task-cache-workspace", ".mise-state", ), }, mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, { label: "multi-root", files: "src/e2e-tests/multi-root/*.e2e.ts", // a `.code-workspace` file, so vscode opens a multi-root workspace whose // folders are subdirectories of the directory holding the file workspaceFolder: multiRootWorkspaceFile, env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "multi-root-workspace", "global-config.toml", ), // the go toolchains the suite installs stay inside the fixture MISE_DATA_DIR: path.join( fixturesPath, "multi-root-workspace", ".mise-data", ), MISE_CACHE_DIR: path.join( fixturesPath, "multi-root-workspace", ".mise-cache", ), }, // golang.go is the extension under test: mise writes `go.goroot` and // `go.alternateTools` for it. shell-format has a window-scoped setting // (`shellformat.path`), which folder-scoped configuration cannot hold. installExtensions: ["golang.go", "foxundermoon.shell-format"], mocha: { require: ["tsx/cjs"], // the go suite installs two toolchains timeout: 600_000, }, }, { label: "multi-root-python", files: "src/e2e-tests/multi-root-python/*.e2e.ts", // a multi-root workspace where a single folder is a python project workspaceFolder: multiRootPythonWorkspaceFile, env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, // Keep the machine's real global config out of the tests, and keep the // python installed by the suite out of the machine's mise data dir. MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "multi-root-python-workspace", "global-config.toml", ), MISE_DATA_DIR: path.join( fixturesPath, "multi-root-python-workspace", ".mise-data", ), MISE_CACHE_DIR: path.join( fixturesPath, "multi-root-python-workspace", ".mise-cache", ), }, // ms-python.python is the extension under test: its interpreter path is // relative to the folder it is written for installExtensions: ["ms-python.python"], mocha: { require: ["tsx/cjs"], // installs a python on a cold cache timeout: 300_000, }, }, { label: "go", files: "src/e2e-tests/go/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "go-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", MISE_TRUSTED_CONFIG_PATHS: fixturesPath, MISE_GLOBAL_CONFIG_FILE: path.join( fixturesPath, "go-workspace", "global-config.toml", ), // shares the toolchain store of the multi-root fixture, so each go // version is downloaded once per CI run MISE_DATA_DIR: path.join( fixturesPath, "multi-root-workspace", ".mise-data", ), MISE_CACHE_DIR: path.join( fixturesPath, "multi-root-workspace", ".mise-cache", ), // keep the build cache in the fixture, and never let go swap in // another toolchain than the one mise resolves GOCACHE: path.join(fixturesPath, "go-workspace", ".gocache"), GOTOOLCHAIN: "local", }, installExtensions: ["golang.go"], mocha: { require: ["tsx/cjs"], // installs a toolchain and compiles the go stdlib on a cold cache timeout: 600_000, }, }, { label: "monorepo", files: "src/e2e-tests/monorepo/*.e2e.ts", workspaceFolder: path.join(fixturesPath, "monorepo-workspace"), env: { MISE_CEILING_PATHS: fixturesPath, MISE_LOCKED: "0", // Pre-trust the fixture configs (including subproject configs) so the // extension never blocks on the trust dialog in CI. MISE_TRUSTED_CONFIG_PATHS: fixturesPath, }, mocha: { require: ["tsx/cjs"], timeout: 60_000, }, }, ]);