Code Coverage report when running Selenium against an Angular App (Remote)

246 Views Asked by At

I can’t find any appropriate solution for my issue online.

We are building a Backend (Java) and an Angular App and deploy it via Docker to a test environment. Now we are running Selenium (Selenide) tests (e2e) against the Frontend Angular application using junit (and selenium tests written in Java). (Remote Web Driver "selenium/standalone-chrome" )

My question is how can I instruct my Angular App to report the code coverage?

I found some articles about Istanbul.js and JS Testframeworks but I don’t want to start the tests in JS! The deployed app should have the source maps and required Istanbul instrumentations. Even if it means that I have to build my containers twice (once for test (with all this stuff) / once for production).

According to this repo, within the selenium test it should be possible to get the coverage from the window:

https://github.com/alex028502/istanbulseleniumexample/blob/master/test.py

coverage_info = _driver.execute_script('return JSON.stringify(window.__coverage__);')

So that shouldn't be the issue - but I dont know how to instruct my angular app to record the code coverage ...

Any advice is welcome ...

1

There are 1 best solutions below

0
max On

Okay - I think I figured it out ..

I installed nyc as a dev dependency npm i -D nyc

Then I added the following scripts to the "package.json":

 "scripts": {
    "build": "ng build && npm run _nyc-instrument",
    "_nyc-instrument": "nyc instrument dist/your-app dist/your-app --exclude-after-remap=false --complete-copy --in-place",
    "_nyc-report": "nyc report --reporter=lcov --reporter=text-summary --report-dir=.coverage-output"
  },

Then I also configured in "angular.json" to create source maps:

  "configurations": {
     "production": {
        "sourceMap": true,
        "budgets": [...

Now if you run npm run build the javascript will be instumented and source map files ".map" will be in the "/dist" folder.

We deploy the angular app within an nginx docker container .. Then we run the selenium tests against the deployed stack ... sample code:

mvn test -Dgroups=ui-tests -DremoteWebDriverUrl=http://seleniumWebDriverUrl} -DbaseUrl=https://${serverDomainName} -Dheadless=true

In the end of every test execution we download the coverage reports from "window.__coverage__" --> here a sample code:

String coverageInfo = (String) WebDriver.executeScript("return JSON.stringify(window.__coverage__);");
Files.createDirectories(Paths.get(filePath));
Files.writeString(Paths.get(filePath, filename), coverageInfo);

The downloaded files should be stored in the angular project in the ".nyc_output/" folder.

Now we run the report command npm run _nyc-report which creates in the output folder ".coverage-output" the "lcov.info" file.

Unfortunately in our case with wrong file path prefixes - this is kind of a known issue ... we fix it with sed (you most probably need to adapt the sed command to your needs):

 sh "sed -i 's|SF:dist/webapp/de/webpack:/|SF:|g' .coverage-output/lcov.info"

An entry in lcov.info should then look like this:

SF:src/main.ts
FN:7,(anonymous_3021)
FN:7,(anonymous_3023)
FNF:2
FNH:1
FNDA:0,(anonymous_3021)
FNDA:235,(anonymous_3023)
DA:5,9
DA:7,253
LF:2
LH:2
BRF:0
BRH:0
end_of_record

Now point sonar to use this file in the "sonar-project.properties" file:

sonar.sources=src
sonar.language=ts
sonar.sourceEncoding=UTF-8
sonar.javascript.lcov.reportPaths=.coverage-output/lcov.info

And finally run the sonar scanner:

sonar-scanner -Dsonar.projectKey=<app-name> -Dsonar.projectVersion=<app-version> ....