JavaScript Tests

CI Visibility is not available in the selected site () at this time.

Compatibility

Supported test frameworks:

  • Jest >= 24.8.0
    • Only jsdom (in package jest-environment-jsdom) and node (in package jest-environment-node) are supported as test environments. Custom environments like @jest-runner/electron/environment in jest-electron-runner are not supported.
    • Only jest-circus and jest-jasmine2 are supported as testRunner.
    • Jest >= 28 is only supported from dd-trace>=2.7.0
  • Mocha >= 5.2.0
  • Cucumber-js >= 7.0.0
  • Cypress >= 6.7.0
    • From dd-trace>=1.4.0

Configuring reporting method

To report test results to Datadog, you need to configure the Datadog JavaScript library:

If you are running tests on an on-premises CI provider, such as Jenkins or self-managed GitLab CI, install the Datadog Agent on each worker node by following the Agent installation instructions. This is the recommended option as test results are then automatically linked to the underlying host metrics.

If the CI provider is using a container-based executor, set the DD_AGENT_HOST environment variable on all builds (which defaults to http://localhost:8126) to an endpoint that is accessible from within build containers, as localhost inside the build references the container itself and not the underlying worker node where the Datadog Agent is running.

If you are using a Kubernetes executor, Datadog recommends using the Datadog Admission Controller, which automatically sets the DD_AGENT_HOST environment variable in the build pods to communicate with the local Datadog Agent.

Agentless mode is available in Datadog JavaScript library versions >= 2.5.0

If you are using a cloud CI provider without access to the underlying worker nodes, such as GitHub Actions or CircleCI, configure the library to use the Agentless mode. For this, set the following environment variables:

DD_CIVISIBILITY_AGENTLESS_ENABLED=true (Required)
Enables or disables Agentless mode.
Default: false
DD_API_KEY (Required)
The Datadog API key used to upload the test results.
Default: (empty)

Additionally, configure which Datadog site to which you want to send data.

DD_SITE (Required)
The Datadog site to upload results to.
Default: datadoghq.com
Selected site:

Installing the JavaScript tracer

To install the JavaScript tracer, run:

yarn add --dev dd-trace

For more information, see the JavaScript tracer installation docs.

Instrument your tests

Set NODE_OPTIONS environment variable to -r dd-trace/ci/init. Run your tests as you normally would, specifying the environment where the tests are run in the DD_ENV environment variable. For example, set DD_ENV to local when running tests on a developer workstation, or ci when running them on a CI provider:

NODE_OPTIONS="-r dd-trace/ci/init" DD_ENV=ci DD_SERVICE=my-javascript-app yarn test

Using Yarn >=2

If you’re using yarn>=2 and a .pnp.cjs file, and you get the following error message when using NODE_OPTIONS:

 Error: Cannot find module 'dd-trace/ci/init'

You can fix it by setting NODE_OPTIONS to the following:

NODE_OPTIONS="-r $(pwd)/.pnp.cjs -r dd-trace/ci/init" yarn test

Adding custom tags to tests

You can add custom tags to your tests by using the current active span:

  it('sum function can sum', () => {
    const testSpan = require('dd-trace').scope().active()
    testSpan.setTag('team_owner', 'my_team')
    // test continues normally
    // ...
  })

To create filters or group by fields for these tags, you must first create facets. For more information about adding tags, see the Adding Tags section of the NodeJS custom instrumentation documentation.

Set the NODE_OPTIONS environment variable to -r dd-trace/ci/init. Run your tests as you normally would, specifying the environment where the tests are run in the DD_ENV environment variable. For example, set DD_ENV to local when running tests on a developer workstation, or ci when running them on a CI provider:

NODE_OPTIONS="-r dd-trace/ci/init" DD_ENV=ci DD_SERVICE=my-javascript-app yarn test

Using Yarn >=2

If you’re using yarn>=2 and a .pnp.cjs file, and you get the following error message when using NODE_OPTIONS:

 Error: Cannot find module 'dd-trace/ci/init'

You can fix this by setting NODE_OPTIONS to the following:

NODE_OPTIONS="-r $(pwd)/.pnp.cjs -r dd-trace/ci/init" yarn test

Adding custom tags to tests

You can add custom tags to your test by grabbing the current active span:

  When('the function is called', function () {
    const stepSpan = require('dd-trace').scope().active()
    testSpan.setTag('team_owner', 'my_team')
    // test continues normally
    // ...
  })

To create filters or group by fields for these tags, you must first create facets. For more information about adding tags, see the Adding Tags section of the NodeJS custom instrumentation documentation.

Cypress<10

These are the instructions if you’re using a version older than cypress@10.

  1. Set pluginsFile to "dd-trace/ci/cypress/plugin", for example through cypress.json:

cypress.json

{
  "pluginsFile": "dd-trace/ci/cypress/plugin"
}

If you’ve already defined a pluginsFile, you can still initialize the instrumentation with:

cypress/plugins/index.js

module.exports = (on, config) => {
  // your previous code is before this line
  require('dd-trace/ci/cypress/plugin')(on, config)
}
  1. Add the following line to the supportFile:

cypress/support/index.js

// your previous code is before this line
require('dd-trace/ci/cypress/support')

Run your tests as you normally do, specifying the environment where test are being run (for example, local when running tests on a developer workstation, or ci when running them on a CI provider) in the DD_ENV environment variable. For example:

DD_ENV=ci DD_SERVICE=my-ui-app npm test

Cypress >=10

Use the Cypress API documentation to learn how to write plugins for cypress>=10.

In your cypress.config.js file, set the following:

cypress.config.js

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    setupNodeEvents: require('dd-trace/ci/cypress/plugin'),
    supportFile: 'cypress/support/index.js'
  }
})

Your supportFile should look the same as in cypress<10:

cypress/support/index.js

// your previous code is before this line
require('dd-trace/ci/cypress/support')

If you’re using other Cypress plugins, your cypress.config.js file should contain the following:

cypress.config.js

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      // your previous code is before this line
      require('dd-trace/ci/cypress/plugin')(on, config)
    }
  }
})

Adding custom tags to tests

To add additional information to your tests, such as the team owner, use cy.task('dd:addTags', { yourTags: 'here' }) in your test or hooks.

For example:

beforeEach(() => {
  cy.task('dd:addTags', {
    'before.each':
    'certain.information'
  })
})
it('renders a hello world', () => {
  cy.task('dd:addTags', {
    'team.owner': 'ui',
    'test.importance': 3
  })
  cy.get('.hello-world')
    .should('have.text', 'Hello World')
})

To create filters or group by fields for these tags, you must first create facets. For more information about custom instrumentation, see the NodeJS Custom Instrumentation documentation.

Cypress - RUM integration

If the browser application being tested is instrumented using RUM, your Cypress test results and their generated RUM browser sessions and session replays are automatically linked. Learn more in the RUM integration guide.

Configuration settings

The following is a list of the most important configuration settings that can be used with the tracer. They can be either passed in on its init() function, or as environment variables:

service
Name of the service or library under test.
Environment variable: DD_SERVICE
Default: (test framework name)
Example: my-ui
env
Name of the environment where tests are being run.
Environment variable: DD_ENV
Default: none
Examples: local, ci
url
Datadog Agent URL for trace collection in the form http://hostname:port.
Environment variable: DD_TRACE_AGENT_URL
Default: http://localhost:8126

All other Datadog Tracer configuration options can also be used.

Collecting Git metadata

Datadog uses Git information for visualizing your test results and grouping them by repository, branch, and commit. Git metadata is automatically collected by the test instrumentation from CI provider environment variables and the local .git folder in the project path, if available.

If you are running tests in non-supported CI providers or with no .git folder, you can set the Git information manually using environment variables. These environment variables take precedence over any auto-detected information. Set the following environment variables to provide Git information:

DD_GIT_REPOSITORY_URL
URL of the repository where the code is stored. Both HTTP and SSH URLs are supported.
Example: git@github.com:MyCompany/MyApp.git, https://github.com/MyCompany/MyApp.git
DD_GIT_BRANCH
Git branch being tested. Leave empty if providing tag information instead.
Example: develop
DD_GIT_TAG
Git tag being tested (if applicable). Leave empty if providing branch information instead.
Example: 1.0.1
DD_GIT_COMMIT_SHA
Full commit hash.
Example: a18ebf361cc831f5535e58ec4fae04ffd98d8152
DD_GIT_COMMIT_MESSAGE
Commit message.
Example: Set release number
DD_GIT_COMMIT_AUTHOR_NAME
Commit author name.
Example: John Smith
DD_GIT_COMMIT_AUTHOR_EMAIL
Commit author email.
Example: john@example.com
DD_GIT_COMMIT_AUTHOR_DATE
Commit author date in ISO 8601 format.
Example: 2021-03-12T16:00:28Z
DD_GIT_COMMIT_COMMITTER_NAME
Commit committer name.
Example: Jane Smith
DD_GIT_COMMIT_COMMITTER_EMAIL
Commit committer email.
Example: jane@example.com
DD_GIT_COMMIT_COMMITTER_DATE
Commit committer date in ISO 8601 format.
Example: 2021-03-12T16:00:28Z

Known limitations

ES modules

Mocha >=9.0.0 uses an ESM-first approach to load test files. That means that if ES modules are used (for example, by defining test files with the .mjs extension), the instrumentation is limited. Tests are detected, but there isn’t visibility into your test. For more information about ES modules, see the NodeJS documentation.

Browser tests

Browser tests executed with mocha, jest, cucumber and cypress are instrumented by dd-trace-js, but visibility into the browser session itself is not provided by default (for example, network calls, user actions, page loads, and so on).

If you want visibility into the browser process, consider using RUM & Session Replay. When using Cypress, test results and their generated RUM browser sessions and session replays are automatically linked. Learn more in the RUM integration guide.

Best practices

Follow these practices to take full advantage of the testing framework and CI Visibility.

Parameterized tests

Whenever possible, leverage the tools that testing frameworks provide for parameterized tests. For example, for jest:

Avoid this:

[[1,2,3], [3,4,7]].forEach((a,b,expected) => {
  test('sums correctly', () => {
    expect(a+b).toEqual(expected)
  })
})

And use test.each instead:

test.each([[1,2,3], [3,4,7]])('sums correctly %i and %i', (a,b,expected) => {
  expect(a+b).toEqual(expected)
})

For mocha, use mocha-each:

const forEach = require('mocha-each');
forEach([
  [1,2,3],
  [3,4,7]
])
.it('adds %i and %i then returns %i', (a,b,expected) => {
  expect(a+b).to.equal(expected)
});

When you use this approach, both the testing framework and CI Visibility can tell your tests apart.

Further reading