# Karma test framework

Gathering coverage and test information using the SeaLights Node.js Test Listener is done in a few steps and commands, detailed below in a table comparing the relevancy of each, depending on the type of tests you’re running

<table><thead><tr><th width="77.66668701171875">Step</th><th width="259">Command</th><th>Unit Tests</th><th>Functional Tests</th></tr></thead><tbody><tr><td>1</td><td>Starting the Test Stage</td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td></tr><tr><td>2</td><td>Executing your application instrumented by Sealights</td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2Fs1SOT5enrcGSGrgJVWOF%2Fclose.svg?alt=media&#x26;token=d416d4cb-ffa9-4a4a-bcbf-24d94174c3d4" alt=""></td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td></tr><tr><td>3</td><td>Run your Karma tests</td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td></tr><tr><td>4.a</td><td>Upload Coverage Report</td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2Fs1SOT5enrcGSGrgJVWOF%2Fclose.svg?alt=media&#x26;token=d416d4cb-ffa9-4a4a-bcbf-24d94174c3d4" alt=""></td></tr><tr><td>4.b</td><td>Upload JUnit Report</td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td></tr><tr><td>5</td><td>End the Test Stage</td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td><td><img src="https://4057366433-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjqTCMRYvHhDgsdPLUnc%2Fuploads%2FHiqKxVnDoOLH0P6P0jAt%2Fcheck_circle.svg?alt=media&#x26;token=15d4ebba-b19c-43c5-9e5b-17b0cc36d41d" alt=""></td></tr></tbody></table>

{% hint style="info" %}
See '[Generating an Agent token](https://docs.sealights.io/knowledgebase/settings/token-access-and-management#token-list-and-token-creation-2)' for instructions on how to generate a token
{% endhint %}

## Starting the Test Stage <a href="#starting-the-test-stage" id="starting-the-test-stage"></a>

First, the SeaLights server needs to be notified that a test stage is starting.

{% code overflow="wrap" %}

```sh
npx slnodejs start --tokenfile /path/to/sltoken.txt --buildsessionidfile buildSessionId --teststage "Unit Tests"ests"
```

{% endcode %}

{% hint style="info" %}
See [#starting-a-test-stage](https://docs.sealights.io/knowledgebase/setup-and-configuration/sealights-agents-and-plugins/command-reference#starting-a-test-stage "mention") for full parameter details
{% endhint %}

## Running your tests <a href="#running-your-tests" id="running-your-tests"></a>

### Functional Tests <a href="#functional-tests" id="functional-tests"></a>

Before running your functional tests, you need to set up your backend or frontend applications to send the coverage to Sealights (test footprints):

* [running-backend-server](https://docs.sealights.io/knowledgebase/setup-and-configuration/sealights-agents-and-plugins/node.js-agent/backend-server-application/running-backend-server "mention")
* [front-end-app-scan-and-instrument](https://docs.sealights.io/knowledgebase/setup-and-configuration/sealights-agents-and-plugins/node.js-agent/front-end-application/front-end-app-scan-and-instrument "mention")

Once set up, you now run your tests normally while generating one or more JUnit XML result files to be reported to the SeaLights server.

### Unit Tests <a href="#unit-tests" id="unit-tests"></a>

To report the test and coverage information to SeaLights, you need to run the karma tests while producing coverage information and a JUnit results file.

* For the JUnit results XML file, you can use the **karma-junit-reporter** reporter.
  * See [npm: karma-junit-reporter](https://www.npmjs.com/package/karma-junit-reporter) for more details.
* For the coverage, you need to use the **karma-coverage** configured to generate a `coverage-final.json` file by using the *coverageReporter* type `json`.
  * See [npm: karma-coverage](https://www.npmjs.com/package/karma-coverage) for more details.

To generate these report files, update your `karma.conf.js` and add or update the `reporters`, `coverageReporter`, and `junitReporter` sections:

{% code overflow="wrap" lineNumbers="true" %}

```
module.exports = function (config) {
  config.set({
    // your existing config...
    reporters: ['progress', 'junit', 'coverage'],

    coverageReporter: {
      type: 'json',
      dir: 'karma-reports',
      subdir: '.',
      file: 'coverage-final.json',
    },

    junitReporter: {
      outputDir: 'karma-reports',
      outputFile: 'junit.xml',
      useBrowserName: false,
    },
  });
};
```

{% endcode %}

## Uploading Test Metadata  <a href="#uploading-test-metadata" id="uploading-test-metadata"></a>

### Upload coverage report files from Unit Tests <a href="#upload-coverage-report-files-from-unit-tests" id="upload-coverage-report-files-from-unit-tests"></a>

Once done running the Unit Tests, you upload the coverage report files to the SeaLights server using the **nycReport** option

{% code overflow="wrap" lineNumbers="true" %}

```sh
npx slnodejs nycReport --tokenfile /path/to/sltoken.txt --buildsessionidfile buildSessionId [--report ./coverage/coverage-final.json]
```

{% endcode %}

### Upload test results report files <a href="#upload-test-results-report-files" id="upload-test-results-report-files"></a>

Once done running the tests, you upload the test results file to the SeaLights server using the **uploadReports** option

{% code overflow="wrap" lineNumbers="true" %}

```sh
npx slnodejs uploadReports --tokenfile /path/to/sltoken.txt --buildsessionidfile buildSessionId --reportFile junit.xml
```

{% endcode %}

## Ending the Test Stage <a href="#ending-the-test-stage" id="ending-the-test-stage"></a>

Finally, the server needs to be notified that a test stage has ended.

{% code overflow="wrap" lineNumbers="true" %}

```sh
npx slnodejs end --tokenfile /path/to/sltoken.txt --buildsessionidfile buildSessionId
```

{% endcode %}

## Sample - Capturing Unit Tests with Karma <a href="#sample-capturing-unit-tests-with-karma" id="sample-capturing-unit-tests-with-karma"></a>

Below, a sample script running the Unit Tests while instrumenting for client-side (front-end) coverage

{% code overflow="wrap" lineNumbers="true" %}

```sh
#Install the project dependencies
npm install

# transpile the code with source maps to the dist folder
npm run build

# Install the SeaLights agents
npm i slnodejs

# Create a SeaLights ignore file to only include the src folder
echo '**/vendor*.js' > .slignore
echo '**/polyfills*.js' >> .slignore

# Scan the source files to provide SeaLights the structure of the project
npx slnodejs scan --tokenfile sltoken.txt --buildsessionidfile buildSessionId --workspacepath dist --scm git --projectRoot $(pwd)
npx slnodejs instrument --tokenfile sltoken.txt --buildsessionidfile buildSessionId --outputpath sl_dist --workspacepath dist 

# Notify SeaLights the Unit Tests are starting
npx slnodejs start --tokenfile sltoken.txt --buildsessionidfile buildSessionId.txt --testStage "Unit Tests"

# Run the unit tests while ignoring the error code returned from Karma if the tests fail
# This should be with coverage and Junit reports enabled - we assume they're placed in the 'karma-reports' folder
set +e
npm run test
set -e

# Upload the coverage and tests results to SeaLights
npx slnodejs nycReport --tokenfile sltoken.txt --buildsessionidfile buildSessionId.txt --report ./karma-reports/coverage-final.json
npx slnodejs uploadReports --tokenfile sltoken.txt --buildsessionidfile buildSessionId.txt --reportFile ./karma-reports/junit.xml

# Notify SeaLights the Unit Tests have finished
npx slnodejs end --tokenfile sltoken.txt --buildsessionidfile buildSessionId.txt
```

{% endcode %}
