# test-samurai-vitest-runner A [test-samurai](https://github.com/your-org/test-samurai.nvim) runner plugin for [Vitest](https://vitest.dev/) (v2.x). Supports Web Component tests with or without shadow DOM via `jsdom`, `happy-dom`, or `@vitest/browser`. ## Requirements - Neovim ≥ 0.10 - [test-samurai.nvim](https://github.com/your-org/test-samurai.nvim) - [plenary.nvim](https://github.com/nvim-lua/plenary.nvim) - Vitest 2.x in your project's `package.json` ## Installation ### lazy.nvim ```lua { "your-org/test-samurai.nvim", dependencies = { "your-org/test-samurai-vitest-runner", }, config = function() require("test-samurai").setup({ runners = { require("test-samurai-vitest-runner"), }, }) end, } ``` ## How it works The runner detects Vitest test files (`*.test.ts`, `*.spec.ts`, etc.) by checking the file name suffix and verifying that `vitest` is listed in the project's `package.json` dependencies. It uses a custom Vitest reporter (`reporter/test_samurai_vitest_reporter.js`) that emits one JSON line per completed test case to stdout: ``` TSAMURAI_RESULT {"name":"MyComponent/renders the slot","status":"passed",...} ``` The `name` field uses `/` to join the describe hierarchy with the test title, e.g. `MyComponent/shadow DOM/assigns slot content`. ### Reporter payload schema | Field | Type | Description | |------------|-------------------------------|------------------------------------------------| | `name` | `string` | Describe hierarchy + test title, joined by `/` | | `status` | `"passed"│"failed"│"skipped"` | Test result | | `file` | `string│null` | Absolute path to the test file | | `location` | `{line, column}│null` | Source location of the test | | `output` | `string[]` | Error messages and stack traces (failures) | ## Setup files If the project root (or `test/.bin/`) contains a `vitest.setup.ts` or `vitest.setup.js` file, the runner passes it via `--setupFiles` automatically. This is useful for Web Component tests that need custom element registration: ```ts // vitest.setup.ts import { MyButton } from './src/my-button.js' if (!customElements.get('my-button')) { customElements.define('my-button', MyButton) } ``` For shadow DOM access in tests use `element.shadowRoot`: ```ts it('renders slot content', async () => { document.body.innerHTML = 'Click me' const el = document.querySelector('my-button')! await el.updateComplete // if using Lit expect(el.shadowRoot!.querySelector('button')!.textContent).toBe('Click me') }) ``` ## Vitest configuration Configure the DOM environment in `vitest.config.ts`: ```ts import { defineConfig } from 'vitest/config' export default defineConfig({ test: { environment: 'happy-dom', // or 'jsdom' setupFiles: ['./vitest.setup.ts'], }, }) ``` ## Commands | Command | Description | |------------------|------------------------------------------| | `TSamNearest` | Run the test nearest to the cursor | | `TSamFile` | Run all tests in the current file | | `TSamAll` | Run all tests in the project | | `TSamLast` | Re-run the last command | | `TSamFailedOnly` | Re-run only the failed tests | | `TSamShowOutput` | Show test output in a floating window | ## Default keymaps | Key | Command | |---------------|----------------| | `tn` | `TSamNearest` | | `tf` | `TSamFile` | | `ta` | `TSamAll` | | `tl` | `TSamLast` | | `te` | `TSamFailedOnly` | | `to` | `TSamShowOutput` | ## Running the plugin tests ```bash bash run_test.sh ``` Tests use [plenary.nvim](https://github.com/nvim-lua/plenary.nvim) + Busted and are located in `tests/`.