This plugin provides a StencilJS adapter for the Neotest framework.
Install the adapter using your plugin manager, for example with lazy.nvim:
{
  "nvim-neotest/neotest",
  dependencies = {
    "benelan/neotest-stenciljs",
    -- other plugins required by neotest ...
  },
  config = function()
    require("neotest").setup({
      adapters = {
        require("neotest-stenciljs")
        -- other adapters ...
      },
      -- other neotest config options ...
    })
  end
}IMPORTANT: Make sure you have the appropriate treesitter language parsers
installed, otherwise no tests will be found:
:TSInstall javascript typescript tsxSee the source code for the available configuration options:
neotest-stenciljs/lua/neotest-stenciljs/init.lua
Lines 7 to 13 in f98366c
An example configuration:
require("neotest").setup({
  adapters = {
    require("neotest-stenciljs")({
      no_build = true,
      env = {
        CI = true,
        PUPPETEER_EXECUTABLE_PATH = "/usr/bin/chromium-browser"
      }
      cwd = function(file_path)
        return vim.fs.dirname(file_path)
      end
    }),
  }
})Use the is_test_file option to add a custom criteria for test file discovery.
This is helpful in monorepos where other packages use Jest or Vitest, which use
similar naming patterns.
---Custom criteria for a file path to determine if it is a stencil test file
---@async
---@param file_path string Path of the potential stencil test file
---@return boolean
is_test_file = function(file_path)
  -- check if the project is "stencil-components" when working in the monorepo
  if
    string.match(file_path, "my-monorepo")
    and not string.match(file_path, "packages/stencil-components")
  then
    return false
  end
  -- this is the default condition
  return string.match(file_path, "%.e2e%.tsx?$")
    or string.match(file_path, "%.spec%.tsx?$")
end,Use the filter_dir option to limit the directories to be searched for tests.
---Filter directories when searching for test files
---@async
---@param name string Name of directory
---@param rel_path string Path to directory, relative to root
---@param root string Root directory of project
---@return boolean
filter_dir = function(name, rel_path, root)
  local full_path = root .. "/" .. rel_path
  if root:match("my-monorepo") then
    return full_path:match("packages/stencil-components/src")
  else
  -- this is the default condition
  return not vim.tbl_contains(
    { "node_modules", "dist", "hydrate", "www", ".stencil", ".storybook" },
    name
  )
  end
endSee neotest's documentation for information on how to run tests.
To always run test(s) with the --watchAll flag, you can enable the option
during setup:
require('neotest').setup({
  adapters = {
    require('neotest-jest')({ watch = true }),
  }
})Alternatively, you can add a specific keymap to run test(s) in watch mode:
vim.keymap.set(
  "n",
  "<leader>tw",
  "<CMD>lua require('neotest').run.run({ watch = true })<CR>",
  { noremap = true, desc = "Run test (watch)" }
)StencilJS provides the --no-build flag to run e2e tests without building. You
can enable the flag during setup:
require('neotest').setup({
  adapters = {
    require('neotest-jest')({ no_build = true }),
  }
})If you used the watch mode keymap method above, make sure to disable the
--no-build flag:
vim.keymap.set(
  "n",
  "<leader>tw",
  "<CMD>lua require('neotest').run.run({ watch = true, no_build = false })<CR>",
  { noremap = true, desc = "Run test (watch)" }
)This adapter currently doesn't work well with Stencil/Jest's
it.each
syntax, but I hope to fix that in the future. Please log an issue if that's
something you want supported.
The adapter also doesn't work well on tests within for/forEach loops. Using
the builtin it.each
or describe.each
syntax should be preferred anyway.
This neotest adapter was originally copied from neotest-jest
and neotest-vitest. StencilJS
uses Jest under the hood, so a
lot of the code remains unchanged.
I am not affiliated, associated, authorized, endorsed by, or in any way officially connected with StencilJS and Ionic. Any information or opinions expressed in this project are solely mine and do not necessarily reflect the views or opinions of StencilJS and Ionic.