Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generating report error - cannot convert undefined or null to object #244

Closed
ArtiomTr opened this issue Mar 5, 2022 · 14 comments
Closed

Comments

@ArtiomTr
Copy link
Owner

ArtiomTr commented Mar 5, 2022

I am also having issues with the latest v2.0.4 and I have a similar setup where I run jest and collect coverage in separate steps and then use ArtiomTr/jest-coverage-report-action for the annotations.

     - name: Jest coverage report
        uses: ArtiomTr/jest-coverage-report-action@v2.0.4
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          coverage-file: ./temp-coverage-results/current/jest.results.json
          base-coverage-file: ./temp-coverage-results/target/jest.results.json
          threshold: 80
          skip-step: all
          annotations: failed-tests

With v2.0.4 it keeps failing with TypeError: Cannot convert undefined or null to object and I am not sure how to debug it.

CleanShot 2022-03-04 at 13 46 25


Out of curiosity I tried to use ArtiomTr/jest-coverage-report-action@Debug-action instead (mentioned in another conversation) and with that particular version it works perfectly every time: branch in not switching, reports are being collected, annotation with coverage diffs is generated, etc..

I did some research but wasn't able to figure out where the Debug-action version comes from... is it based on an older version?! @ArtiomTr

Originally posted by @raspo in #242 (comment)

@ArtiomTr
Copy link
Owner Author

ArtiomTr commented Mar 5, 2022

Related: #242 (comment)

@raspo,

The Debug-action is not a version, it is a branch. I created it from the main branch, so it should be the same as v2.0.4 version, with few console.log's added.

Looks like error occur on this line

const total = Object.values(map).reduce(

The variable map is null or undefined. I don't know what could cause that issue, but it is definitely is not related to this one. I will create a separate issue for this.

@raspo
Copy link
Contributor

raspo commented Mar 7, 2022

This appears to be fixed with the latest version v2.0.5 🎉
I think we can close the issue.

@ArtiomTr ArtiomTr closed this as completed Mar 7, 2022
@coelhucas
Copy link

coelhucas commented Mar 25, 2022

I just faced this same (I believe) issue:

image

My first run was without any threshold set, this was after adding it (not sure if it has relation, need further runs to check it)

@raspo
Copy link
Contributor

raspo commented Mar 25, 2022

@coelhucas what's your config? were you using version 2.0.5?
uses: ArtiomTr/jest-coverage-report-action@v2.0.5

@lockettks
Copy link

I'm running into what seems to be the same issue as well using v2.0.5. I'm manually generating the coverage report in the previous step and skipping the steps in this coverage report action, but I get what seems to be the same error as above.
Screen Shot 2022-04-11 at 9 13 05 PM
Screen Shot 2022-04-11 at 9 15 41 PM
.

@raspo
Copy link
Contributor

raspo commented Apr 12, 2022

I have also started to see this error on another repo I have been working on.
Like @lockettks I am also on v2.05 and I am manually generating both reports.

      - name: Jest coverage report
        uses: ArtiomTr/jest-coverage-report-action@v2.0.5
        with:
          coverage-file: ./temp-coverage-results/current/coverage-final.json
          base-coverage-file: ./temp-coverage-results/target/coverage-final.json
          skip-step: all
          annotations: failed-tests

CleanShot 2022-04-12 at 09 39 41@2x

@ArtiomTr I'd be happy to help debug this, is there a branch or version of this action I can use that can help understand where exactly it is breaking? ideally one that isn't minimized? I think we should re-open this issue, btw.

@raspo
Copy link
Contributor

raspo commented Apr 12, 2022

Update:
I did some digging and I think I figured out the problem.

The type error I posted above seem to occur here:

Object.entries(jsonReport.coverageMap).reduce<FileCoverageMap>(
(with jsonReport.coverageMap resulting in undefined)


There are two ways to generate a JSON code coverage report with Jest:

  1. generate the test results in json format, ie: jest --coverage --json --outputFile="my-report.json"
  2. use json as one of the coverageReporters, ie: jest --coverage --coverageReporters="json"

With option #1 you get a single file (my-report.json) containing test results and the coverage information under the key coverageMap. With option #2 you get a json file (coverage/coverage-final.json) containing only the coverage data; hence it doesn't have a coverageMap key.

Me and @lockettks were clearly using #2 (as you can see by the file name coverage-final.json).


What do you suggest we should do @ArtiomTr ?

I could very easily add a silly check like: const coverageMap = jsonReport.coverageMap || jsonReport; but I'm not sure what would be its impact, as I see .coverageMap being accessed in multiple places...

Should the action trigger an error when the format of the json report is not what it expects?

@ArtiomTr
Copy link
Owner Author

Hello @raspo 👋,

Flags, which are required for generating report are --json --testLocationInResults --outputFile=<filename>. Action automatically modifies your test script and adds necessary flags, so unless you're generating a report file by yourself, remove all additional flags

'--ci',
// telling jest that output should be in json format
'--json',
// force jest to collect coverage
'--coverage',
// argument which tells jest to include tests' locations in the generated json output
'--testLocationInResults',
// output file
`--outputFile="${outputFile}"`,

As for the issue, yes, I think the action should throw errors when the report format doesn't match since the action will lose a lot of functionality if the rest of the fields are missing.

About the debugging, I will create a separate issue on this. Action should generate source maps, to make errors more readable.

@raspo
Copy link
Contributor

raspo commented Apr 13, 2022

Makes sense 👌
Personally, I got confused by the name of the two properties: base-coverage-file and coverage-file, thinking that just providing the coverage file should be ok. We may wanna rename them to something that conveys the idea that this is the full json test report file (like base-json-test-report or base-json-output-file) ... although it's probably not a good idea as it will require a breaking change.

@ArtiomTr
Copy link
Owner Author

@raspo,

Yes, you're right, renaming options will require a breaking change, but I understand your indignation at the incomprehensibility of the option name. I will consider renaming it.

@Crafoord
Copy link

Crafoord commented Sep 23, 2022

@ArtiomTr

I've been using this tool with jest reports but I'm converting to vitest. But I can't manage to get a json from vitest that contains the coverageMap property. Any ideas?

@ArtiomTr
Copy link
Owner Author

Hello @Crafoord 👋,

I'm not familiar with vitest, so this requires some time for investigating.

@nowyDEV
Copy link

nowyDEV commented Sep 28, 2022

This simple script does the job

./scripts/save-coverage-file.js

const fs = require("fs");

/*
  don't forget to update `coverage-file` input inside workflow when specifying path here
  `test.yml`
  with:
    coverage-file: ./coverage/report.json
*/
const testReportFilename = process.cwd() + "/coverage/report.json"; 
const coverageReportFilename = process.cwd() + "/coverage/coverage-final.json";

const testReport = require(testReportFilename);
const coverageReport = require(coverageReportFilename);

testReport.coverageMap = coverageReport;

fs.writeFile(testReportFilename, JSON.stringify(testReport), (err) => {
  if (err) {
    console.error(err);
    process.exit(1);
  }

  console.log("Coverage report appended to " + testReportFilename);
});

package.json

{
  "scripts": {
    "test:coverage": "vitest run --coverage",
    "test:coverage:ci": "npm run test:coverage -- --outputFile ./coverage/report.json && ./scripts/save-test-coverage.js",
  }
}

@GabLeRoux
Copy link

I used a very similar solution to #244 (comment). It's pretty much same solution but a bit more verbose and I actually had to add --reporter=json to the vitest command for it to generate the desired report.json 👍

ci/save-coverage-file.js

#!/usr/bin/env node
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require('fs');

const reportFilename = 'report.json';
const coverageFinalFilename = 'coverage-final.json';
const cwd = process.cwd();

const reportJsonFilepath = `${cwd}/coverage/${reportFilename}`;
const coverageFinalFilepath = `${cwd}/coverage/${coverageFinalFilename}`;

let reportJsonFile;
let coverageFinalJsonFile;

if (fs.existsSync(reportJsonFilepath)) {
    reportJsonFile = require(reportJsonFilepath);
}
if (fs.existsSync(coverageFinalFilepath)) {
    coverageFinalJsonFile = require(coverageFinalFilepath);
}

console.log('Files exists?', { reportFilename: !!reportJsonFile, coverageFinalFilename: !!coverageFinalJsonFile });
if (reportJsonFile && coverageFinalJsonFile) {
    if (!reportJsonFile.coverageMap) {
        console.log(`Adding coverageMap property to ${reportFilename} based on ${coverageFinalFilename}`);
        reportJsonFile.coverageMap = coverageFinalJsonFile;
        fs.writeFileSync(reportJsonFilepath, JSON.stringify(reportJsonFile), (err) => {
            if (err) {
                console.error(err);
                process.exit(1);
            }
        });
    } else {
        console.log(`coverageMap already exists in ${reportFilename}, not doing anything...`);
        process.exit(0);
    }
} else {
    console.log('Not doing anything...');
    process.exit(0);
}

package.json

"scripts": {
    "test:coverage": "vitest run --coverage",
    "test:coverage:ci": "vitest run --coverage --reporter=json --outputFile ./coverage/report.json && ./ci/save-coverage-file.js",
  },

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

No branches or pull requests

7 participants