Skip to content

feat(plugin-coverage): add setup wizard binding#1273

Open
hanna-skryl wants to merge 4 commits intomainfrom
coverage-plugin-binding
Open

feat(plugin-coverage): add setup wizard binding#1273
hanna-skryl wants to merge 4 commits intomainfrom
coverage-plugin-binding

Conversation

@hanna-skryl
Copy link
Collaborator

@hanna-skryl hanna-skryl commented Mar 19, 2026

Closes #1254

Coverage plugin binding for the setup wizard. Auto-detects Jest/Vitest, prompts for coverage options with smart defaults, and generates plugin initialization code.

For Jest/Vitest, generateConfig receives the wizard's virtual tree and uses magicast (0.3.x, as the latest 0.5.x is incompatible with our moduleResolution: "node") to add an LCOV reporter to the test config. If the modification fails, a comment is prepended to pluginInit to remind the user to configure LCOV manually.

@nx-cloud
Copy link

nx-cloud bot commented Mar 19, 2026

View your CI Pipeline Execution ↗ for commit 9bc20e0

Command Status Duration Result
nx run ci:code-pushup -- merge-diffs --files=/h... ✅ Succeeded 5s View ↗
nx run-many --targets=code-pushup --parallel=fa... ✅ Succeeded 1m 36s View ↗
nx run-many --targets=code-pushup --parallel=fa... ✅ Succeeded 13m 41s View ↗
nx run-many -t unit-test,int-test ✅ Succeeded 3s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-19 20:46:02 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 19, 2026

Open in StackBlitz

@code-pushup/ci

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/ci@1273

@code-pushup/cli

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/cli@1273

@code-pushup/core

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/core@1273

@code-pushup/create-cli

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/create-cli@1273

@code-pushup/models

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/models@1273

@code-pushup/nx-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/nx-plugin@1273

@code-pushup/axe-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/axe-plugin@1273

@code-pushup/coverage-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/coverage-plugin@1273

@code-pushup/js-packages-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/js-packages-plugin@1273

@code-pushup/eslint-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/eslint-plugin@1273

@code-pushup/jsdocs-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/jsdocs-plugin@1273

@code-pushup/lighthouse-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/lighthouse-plugin@1273

@code-pushup/typescript-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/typescript-plugin@1273

@code-pushup/utils

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/utils@1273

commit: 9bc20e0

@github-actions
Copy link
Contributor

github-actions bot commented Mar 19, 2026

Code PushUp

🤨 Code PushUp report has both improvements and regressions – compared current commit cc4e3f8 with previous commit 28ccfcb.

🕵️ See full comparison in Code PushUp portal 🔍

🏷️ Categories

🏷️ Category ⭐ Previous score ⭐ Current score 🔄 Score change
Performance 🔴 36 🔴 33 ↓ −2.7
Updates 🟡 72 🟡 73 ↑ +0.7
Documentation 🟡 52 🟡 52 ↓ −0.1
Code coverage 🟢 92 🟢 92 ↑ +0.1
Bug prevention 🟡 75 🟡 75 ↓ −0.1
Axe Accessibility 🟡 88 🟡 88 ↓ −0.1
Code style 🟢 100 🟢 100
Security 🔴 0 🔴 0
Type Safety 🟡 67 🟡 67
Miscellaneous 🟡 67 🟡 67
Accessibility 🟢 92 🟢 92
Best Practices 🟢 100 🟢 100
SEO 🟢 92 🟢 92
👍 2 groups improved, 👎 2 groups regressed, 👍 5 audits improved, 👎 6 audits regressed, 16 audits changed without impacting score

🗃️ Groups

🔌 Plugin 🗃️ Group ⭐ Previous score ⭐ Current score 🔄 Score change
Lighthouse Performance 🔴 36 🔴 33 ↓ −2.7
JS packages npm outdated dependencies 🟡 72 🟡 73 ↑ +0.7
JSDocs coverage Documentation coverage 🟡 52 🟡 52 ↓ −0.1
Code coverage Code coverage metrics 🟢 92 🟢 92 ↑ +0.1

30 other groups are unchanged.

🛡️ Audits

🔌 Plugin 🛡️ Audit 📏 Previous value 📏 Current value 🔄 Value change
Lighthouse Speed Index 🟥 6.1 s 🟥 7.0 s ↑ +14.7 %
Lighthouse Total Blocking Time 🟥 2,050 ms 🟥 2,760 ms ↑ +34.7 %
Lighthouse First Contentful Paint 🟥 3.3 s 🟥 3.4 s ↑ +3.3 %
Lighthouse Max Potential First Input Delay 🟥 710 ms 🟥 1,450 ms ↑ +104.8 %
JS packages Outdated npm prod dependencies. 🟨 22 outdated package versions (7 major, 12 minor, 3 patch) 🟨 23 outdated package versions (7 major, 13 minor, 3 patch) ↑ +4.5 %
JSDocs coverage Variables coverage 🟥 291 undocumented variables 🟥 302 undocumented variables ↑ +3.8 %
JSDocs coverage Functions coverage 🟥 635 undocumented functions 🟥 646 undocumented functions ↑ +1.7 %
JSDocs coverage Types coverage 🟥 279 undocumented types 🟥 281 undocumented types ↑ +0.7 %
Code coverage Function coverage 🟩 94 % 🟩 94 % ↑ +0.1 %
Code coverage Line coverage 🟩 92.1 % 🟩 92.2 % ↑ +0.1 %
Code coverage Branch coverage 🟨 89.1 % 🟨 89.1 % ↑ +0.1 %
Lighthouse Avoids enormous network payloads 🟩 Total size was 2,417 KiB 🟩 Total size was 2,425 KiB ↑ +0.3 %
Lighthouse Largest Contentful Paint 🟥 14.0 s 🟥 9.5 s ↓ −32.5 %
Lighthouse Minimizes main-thread work 🟥 10.3 s 🟥 12.7 s ↑ +22.7 %
Lighthouse Uses efficient cache policy on static assets 🟨 31 resources found 🟨 31 resources found ↑ +0.3 %
Lighthouse Server Backend Latencies 🟩 1,390 ms 🟩 290 ms ↓ −78.9 %
Lighthouse Reduce unused JavaScript 🟥 Potential savings of 298 KiB 🟥 Potential savings of 296 KiB ↓ −29 %
Lighthouse JavaScript execution time 🟥 3.3 s 🟥 3.9 s ↑ +16.6 %
Lighthouse Remove duplicate modules in JavaScript bundles 🟥 Potential savings of 112 KiB 🟥 Potential savings of 109 KiB ↓ −61.9 %
Lighthouse Reduce unused CSS 🟥 Potential savings of 111 KiB 🟥 Potential savings of 111 KiB ↑ +26 %
Lighthouse Initial server response time was short 🟩 Root document took 500 ms 🟩 Root document took 550 ms ↑ +9.5 %
Lighthouse Time to Interactive 🟥 14.7 s 🟥 14.7 s ↓ −0.3 %
Lighthouse Metrics 🟩 100% 🟩 100% ↓ −0.3 %
Lighthouse Network Round Trip Times 🟩 50 ms 🟩 60 ms ↑ +11.9 %
JS packages Outdated npm dev dependencies. 🟨 61 outdated package versions (32 major, 24 minor, 5 patch) 🟨 62 outdated package versions (32 major, 24 minor, 6 patch) ↑ +1.6 %
Lighthouse Avoids an excessive DOM size 🟥 2,348 elements 🟥 2,347 elements ↓ −0.1 %
Lighthouse Cumulative Layout Shift 🟩 0 🟩 0 ↓ −100 %

651 other audits are unchanged.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 19, 2026

Code PushUp

🤨 Code PushUp report has both improvements and regressions – compared current commit cc4e3f8 with previous commit 28ccfcb.

💼 Project plugin-coverage

🤨 Code PushUp report has both improvements and regressions.

🕵️ See full comparison in Code PushUp portal 🔍

🏷️ Category ⭐ Previous score ⭐ Current score 🔄 Score change
Code coverage 🟢 92 🟢 93 ↑ +1.5
Documentation 🟡 69 🟡 68 ↓ −1

4 other categories are unchanged.

👍 1 group improved, 👎 1 group regressed, 👍 3 audits improved, 👎 1 audit regressed, 2 audits changed without impacting score

🗃️ Groups

🔌 Plugin 🗃️ Group ⭐ Previous score ⭐ Current score 🔄 Score change
Code coverage Code coverage metrics 🟢 92 🟢 93 ↑ +1.5
JSDocs coverage Documentation coverage 🟡 69 🟡 68 ↓ −1

13 other groups are unchanged.

🛡️ Audits

🔌 Plugin 🛡️ Audit 📏 Previous value 📏 Current value 🔄 Value change
JSDocs coverage Functions coverage 🟥 22 undocumented functions 🟥 33 undocumented functions ↑ +50 %
Code coverage Function coverage 🟩 93.5 % 🟩 95.7 % ↑ +2.2 %
Code coverage Line coverage 🟨 89.1 % 🟩 91 % ↑ +2.2 %
Code coverage Branch coverage 🟨 89.6 % 🟨 89.7 % ↑ +0.1 %
JSDocs coverage Variables coverage 🟥 13 undocumented variables 🟥 24 undocumented variables ↑ +84.6 %
JSDocs coverage Types coverage 🟥 8 undocumented types 🟥 10 undocumented types ↑ +25 %

438 other audits are unchanged.

💼 Project models

🤨 Code PushUp report has both improvements and regressions.

🕵️ See full comparison in Code PushUp portal 🔍

🏷️ Category ⭐ Previous score ⭐ Current score 🔄 Score change
Documentation 🟡 67 🟡 67 ↑ +0.1
Code coverage 🟢 94 🟢 94 ↓ −0.1

2 other categories are unchanged.

👍 1 group improved, 👎 1 group regressed, 👍 1 audit improved, 👎 1 audit regressed

🗃️ Groups

🔌 Plugin 🗃️ Group ⭐ Previous score ⭐ Current score 🔄 Score change
JSDocs coverage Documentation coverage 🟡 67 🟡 67 ↑ +0.1
Code coverage Code coverage metrics 🟢 94 🟢 94 ↓ −0.1

10 other groups are unchanged.

🛡️ Audits

🔌 Plugin 🛡️ Audit 📏 Previous value 📏 Current value 🔄 Value change
JSDocs coverage Types coverage 🟥 64 undocumented types 🟥 64 undocumented types  +0 %
Code coverage Line coverage 🟩 95 % 🟩 94.6 % ↓ −0.4 %

435 other audits are unchanged.

💼 Project create-cli

🥳 Code PushUp report has improved.

🕵️ See full comparison in Code PushUp portal 🔍

🏷️ Category ⭐ Previous score ⭐ Current score 🔄 Score change
Code coverage 🟢 90 🟢 90 ↑ +0.1

5 other categories are unchanged.

👍 1 group improved, 👍 1 audit improved

🗃️ Groups

🔌 Plugin 🗃️ Group ⭐ Previous score ⭐ Current score 🔄 Score change
Code coverage Code coverage metrics 🟢 90 🟢 90 ↑ +0.1

14 other groups are unchanged.

🛡️ Audits

🔌 Plugin 🛡️ Audit 📏 Previous value 📏 Current value 🔄 Value change
Code coverage Line coverage 🟩 91.2 % 🟩 91.2 % ↑ +0.1 %

442 other audits are unchanged.


11 other projects are unchanged.

@hanna-skryl hanna-skryl marked this pull request as ready for review March 19, 2026 00:28
@hanna-skryl hanna-skryl requested a review from matejchalk as a code owner March 19, 2026 00:28
Copy link
Collaborator

@matejchalk matejchalk left a comment

Choose a reason for hiding this comment

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

The new adjustments mechanism is very elegant. 👍

Comment on lines +91 to +94
it('should return CJS config unchanged', () => {
const input = `module.exports = { coverageReporters: ['text'] };`;
expect(addLcovReporter(input, 'jest')).toBe(input);
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

Aren't we able to add LCOV to CommonJS configs as well? I'm guessing that CommonJS configs are still very common for Jest.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

magicast doesn't support CJS, and your comment made me think about the other cases where we can't reliably modify the config either (factory functions, variable references, missing files). Instead of trying to cover every edge case, I decided to make the binding tell the user when manual setup is needed.

generateConfig now receives the wizard's virtual tree, tries to add the LCOV reporter, and if it can't for any reason, prepends a comment to the generated plugin code.

The tree parameter is a minimal { read, write } contract that bindings can ignore if they don't need to modify files. It's not ideal to expose the tree this way, but I couldn't think of better alternatives. The LCOV change is arguably a side effect, but at the same time, failing to complete it would render the coverage plugin setup incomplete 😕

Let me know if you have other ideas for handling this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

generateConfig now receives the wizard's virtual tree, tries to add the LCOV reporter, and if it can't for any reason, prepends a comment to the generated plugin code.

This is a very good solution. I like it a lot. 🙂

It's not ideal to expose the tree this way

I think it's OK. All changes go through the tree; that's the main thing.

Copy link
Collaborator

@matejchalk matejchalk left a comment

Choose a reason for hiding this comment

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

(I clicked Approve automatically without thinking. 🤦)

generateConfig: (
answers: Record<string, PluginAnswer>,
) => PluginCodegenResult;
tree?: PluginSetupTree,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is tree optional? Is there a scenario when it shouldn't be provided? 🤔

it('should omit coverageToolCommand when test command is empty', async () => {
const { pluginInit } = await generateConfig({
'coverage.testCommand': '',
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is somewhat nuanced, but I prefer to have the execution of the function we're testing - coverageSetupBinding.generateConfig in this case - very explicit and transparent within the test.

That means instead of:

await generateConfig();

await generateConfig({
  'coverage.testCommand': '',
});

It would be:

await coverageSetupBinding.generateConfig(defaultOptions, tree);

await coverageSetupBinding.generateConfig({
  ...defaultOptions,
  'coverage.testCommand': '',
}, tree);

BTW, if coverageSetupBinding is too verbose, you could rename it to something shorter like binding, which is still unambiguous in the context of this test file.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Coverage plugin setup wizard

2 participants