Skip to content

feat: integrate StrykerJS with Vitest setup #8811 - #8949

Open
CoDe-ReDz wants to merge 6 commits into
LibreSign:mainfrom
CoDe-ReDz:main
Open

CoDe-ReDz wants to merge 6 commits into
LibreSign:mainfrom
CoDe-ReDz:main

Conversation

@CoDe-ReDz

@CoDe-ReDz CoDe-ReDz commented Oct 1, 2026 •

Copy link
Copy Markdown

Resolves: #8811

📝 Summary

This PR adds the minimum StrykerJS configuration required to run frontend mutation testing locally using our existing Vitest setup, adhering strictly to the KISS and YAGNI principles.

Changes included:

  • Installed @stryker-mutator/core and @stryker-mutator/vitest-runner as dev dependencies.
  • Added stryker.config.mjs, configured to reuse vitest.config.js to ensure a single source of truth for aliases, mocks, and environment variables.
  • Added server.fs.strict: false to vitest.config.js: the Stryker sandbox links node_modules from outside its root, and Vite otherwise rejects those files (Denied ID).
  • Made the suite pass under --pool threads. @stryker-mutator/vitest-runner forces that pool and ignores pool: 'vmForks', and under threads Node tried to load .css files imported by some packages. The packages that import CSS are now inlined (@nextcloud/vue, @nextcloud/vue-select, @nextcloud/dialogs, @nextcloud/password-confirmation, splitpanes, vue-select) so Vitest processes them. Since @nextcloud/dialogs now runs inside Vitest, three specs (router, DocumentValidationLogic, FileRequestFlow) needed detectLogLevel added to their existing @nextcloud/logger mock. No production code changed.
  • Configured mutate to target src/**/*.{js,ts}, excluding src/tests/** and *.d.ts. .vue files are not mutated: Stryker's instrumentation inserts helper calls into defineOptions()/defineProps() arguments, which Vue's compiler rejects in <script setup>, so the initial test run crashes.
  • Added ignorePatterns so the sandbox does not copy folders Vitest does not use (vendor, PHP, build output).
  • Added /reports/ and /.stryker-tmp/ to .gitignore and .stryker-tmp to the ESLint ignores.
  • Added the test:mutation script to package.json.

No CI quality gates, dashboard services, or blocking thresholds were introduced.

🧪 How to test

To avoid GitHub Codespace memory limits, a full mutation run over all source files ( mutants) is not practical locally. These steps verify the integration instead.

  1. Install the new dependencies:
npm ci
  1. Verify the standard test suite remains unaffected, and that it also passes with the pool Stryker uses:
   npx vitest run --pool threads
  1. Verify type checking still passes:
   npm run ts:check
  1. Verify the initial test run succeeds for the whole mutate set (no mutants are tested):
   npm run test:mutation -- --dryRunOnly
  1. Verify: The terminal should complete the initial test run successfully (proving the --pool threads configuration is stable) and output.
   The dry-run has been completed successfully.

🎨 UI / Front‑end changes

  • Integrated StrykerJS mutation testing framework with existing Vitest configuration.
  • Updated vitest.config.js to permit sandbox file resolution and fix CSS thread pool crashes.
  • Screenshots before/after (add images or links) - N/A (Tooling change only)
  • Tested in multiple browsers (Chrome, Firefox, Safari) - N/A
  • Components, Unit (with vitest) and/or e2e (with Playwright) tests added - Mutation testing tooling added
  • Accessibility verified (contrast, keyboard navigation, screen reader friendly) - N/A
  • Design review approved - N/A
  • Documentation updated (if applicable)

🚧 Tasks

  • Ensure normal Vitest suite passes without modifications.
  • Verify GitHub Codespace constraints are bypassed during focused runs.

✅ Checklist

  • I have read and followed the contribution guide.
  • Official StrykerJS core and Vitest-runner dependencies are installed.
  • npm run test:mutation script exists.
  • Exclusions have a technical reason and are not used to hide surviving mutants (Vue compiler bug).

🤖 AI (if applicable)

  • The content of this PR was partially or fully generated using AI

@CoDe-ReDz
CoDe-ReDz requested a review from a team as a code owner October 1, 2026 06:46
Signed-off-by: Yash Rastogi <98934035+CoDe-ReDz@users.noreply.github.com>
@vitormattos

Copy link
Copy Markdown
Member

@CoDe-ReDz check the CI issues

@LibreSign LibreSign deleted a comment from codecov-commenter Oct 1, 2026
@CoDe-ReDz

Copy link
Copy Markdown
Author

@vitormattos on it!

…issues

Signed-off-by: Yash Rastogi <98934035+CoDe-ReDz@users.noreply.github.com>

@YvesCesar YvesCesar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @CoDe-ReDz !
Many thanks for your contribution.

The description mentions adding server.fs.strict: false to vitest.config.js, but that file is not part of the diff. Please either push that change or update the description.

Comment thread stryker.config.mjs
Comment thread stryker.config.mjs
Comment thread stryker.config.mjs
Comment thread eslint.config.mjs Outdated
…nfig

Signed-off-by: Yash Rastogi <98934035+CoDe-ReDz@users.noreply.github.com>
@CoDe-ReDz

Copy link
Copy Markdown
Author

Hi @YvesCesar! Thank you for the thorough review and the excellent tip regarding the CSS imports. I've pushed an update addressing all of your points:

  1. server.fs.strict: false: This has now been properly committed.
  2. Vitest --pool threads & CSS: Fixed! I updated the CSS processing in vitest.config.js and added the necessary mocks. The full suite (257 files) now passes flawlessly under the threads pool without throwing the Unknown file extension ".css" error.
  3. Stryker ignorePatterns: Added the requested ignore patterns to stryker.config.mjs.
  4. .gitignore: Added /reports/ and /.stryker-tmp/.
  5. ESLint: Fixed the spacing/indentation in eslint.config.mjs.

Note on npm run test:mutation: The dry run now completes successfully! During testing, I discovered that Stryker's instrumentation currently chokes on Vue's defineOptions() compiler macro (crashing on files like App.vue and External.vue). To unblock the initial test run, I have added !src/**/*.vue to the mutate array. This allows Stryker to successfully mutate and test all underlying JS/TS logic files while we look into the Vue instrumentation edge-case separately.

@CoDe-ReDz
CoDe-ReDz requested a review from YvesCesar October 6, 2026 10:26

@YvesCesar YvesCesar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @CoDe-ReDz

I have a few more revisions. Could you take a look at them?

Comment thread vitest.config.js
Comment thread src/tests/components/LeftSidebar/LeftSidebar.spec.ts Outdated
Comment thread stryker.config.mjs Outdated
Comment thread stryker.config.mjs Outdated
Signed-off-by: Yash Rastogi <98934035+CoDe-ReDz@users.noreply.github.com>
@CoDe-ReDz
CoDe-ReDz requested a review from YvesCesar October 6, 2026 20:54
@CoDe-ReDz

Copy link
Copy Markdown
Author

Thanks @YvesCesar, all points addressed in :

  • vitest.config.js: narrowed inline to the list you suggested. npm test and npx vitest run --pool threads both pass ( files).
  • Specs: reverted the other 8; only router, DocumentValidationLogic and FileRequestFlow keep the detectLogLevel mock.
  • LeftSidebar.spec.ts: reverted, so the non-admin tests run as non-admin again.
  • stryker.config.mjs: mutate simplified as suggested (with a comment on why .vue is not mutated), and the SPDX header now matches vite.config.mjs.
  • npm run test:mutation -- --dryRunOnly passes the initial test run for the full mutate set.
  • PR description updated to match.

@YvesCesar

Copy link
Copy Markdown
Member

@vitormattos

Looks ok to me.

@CoDe-ReDz

Copy link
Copy Markdown
Author

@vitormattos could you please review the PR
Thanks!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate StrykerJS with the existing Vitest setup

3 participants