cenfun / monocart-reporter

A playwright test reporter (Node.js)
https://cenfun.github.io/monocart-reporter/
MIT License
200 stars 12 forks source link

[Improve] Better typings for `toIstanbul` code coverage option #70

Closed edumserrano closed 10 months ago

edumserrano commented 10 months ago

When using the toIstanbul option there's no real documentation or code typings to guide the user in what are valid istanbul reporter configurations. The docs say:

toIstanbul (Boolean) Whether to convert to Istanbul report from V8 list. Defaults to html-spa report | (String) report name | (Array) multiple reports. V8 only.

And if I look at the option of (Array) multiple reports the only typing I get in the code is that the array is an array of IstanbulReportConfig which is defined as:

export type IstanbulReportConfig = {
    name: string,
    options: any
}

See lib/index.d.ts.

When researching I found:

Which allowed me to understand the options I could use when configuring the toIstanbul property. One thing that could help is perhaps add the two above links to the monocart-reporter docs. However I ended taking a dependency on my project on @types/istanbul-reports and created the createIstanbulReportConfig helper function:

import { ReportOptions } from 'istanbul-reports';
import { IstanbulReportConfig } from 'monocart-reporter';

function createIstanbulReportConfig<T extends keyof ReportOptions>(
  name: T,
  options?: Partial<ReportOptions[T]>
): IstanbulReportConfig {
  return { name, options };
}

Then I use it like this:

const instanbulReporters: IstanbulReportConfig[] = [
  createIstanbulReportConfig('cobertura', {
    file: 'code-coverage.cobertura.xml',
  }),
  createIstanbulReportConfig('lcovonly', {
    file: 'code-coverage.lcov.info',
  }),
  createIstanbulReportConfig('html-spa', {
    subdir: "code-coverage-html-spa-report",
  }),
];

{
  name: 'playwright code coverage with monocart reporter',
  outputFile: ...,  
  coverage: {
    toIstanbul: instanbulReporters
  },
},

The good thing about the createIstanbulReportConfig is that it won't let you create IstanbulReportConfig instances with invalid name or option properties.

Would you consider including something similar in your library? What do you think?

edumserrano commented 10 months ago

I've just had a play with the recently released v2.0.0 of the monocart-reporter package and instead of the above, I can now do the following:

1) install the package monocart-coverage-reports: npm i -D monocart-coverage-reports@latest 2) Update the playwright.config.ts to use the new ReporterDescription type from monocart-coverage-reports. Example:

// playwright.config.ts

import { ReportDescription } from 'monocart-coverage-reports';

const _codeCoverageReports: ReportDescription[] = [
  ['v8'],
  ['cobertura', {
    file: 'cobertura/code-coverage.cobertura.xml',
  }],
  ['lcovonly', {
    file: 'lcov/code-coverage.lcov.info',
  }],
  ['html-spa', {
    subdir: 'html-spa-report',
  }],
];

export default defineConfig({
  testDir: './tests',
  outputDir: './tests/test-results'
  ...
  reporter: [
    ...
    [
      'monocart-reporter',
      {
        name: 'playwright code coverage with monocart reporter',
        outputFile:  './tests/test-results/monocart-report.html',
        coverage: {
          outputDir: './tests/test-results/code-coverage',
          reportPath: './tests/test-results/code-coverage/v8/index.html',
          reports: _codeCoverageReports
        }
      }
  ]
  ...
});

The ReportDescription type does provide the necessary typings to understand the possible configuration values and avoid making mistakes when configuring the coverage.reports options. πŸŽ‰

I'm already happy enough with this "workaround" but I still want to ask if there's anything that can be done about the typing information we get for the coverage.reports. It shows as (string | (string | {})[])[]:

image

Would it be possible for the coverage.reports to instead display as a ReportDescription[] ?

cenfun commented 10 months ago

more types added in version 2.0.1, example:

import type { MonocartReporterOptions, CoverageReportOptions, ReportDescription } from "monocart-reporter";

const reportsList:ReportDescription[] = [
  ["v8", { outputFile: "index.html", assetsPath:"./assets"}],
  ["html", { subdir: "sub"}]
]

const coverageOptions:CoverageReportOptions = {
      outputDir:"coverage-reports",
      reports: reportsList
}

const monocartOptions:MonocartReporterOptions = {
  name: 'Playwright Report',
  coverage: coverageOptions
};

// playwright config
export default defineConfig({

  reporter: [
    ['list'],
    ['monocart-reporter', monocartOptions]
  ],

})
edumserrano commented 10 months ago

I love this. Great addition, I can confirm this is working exactly like you showed on the code sample above πŸŽ‰