npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wdio/reporter

v9.27.0

Published

A WebdriverIO utility to help reporting all events

Readme

WebdriverIO Reporter

A WebdriverIO utility to help reporting all events

The @wdio/reporter package can be used to create own custom reporter and publish them to NPM. They have to follow a specific convention as described below in order to work properly. First you need to add @wdio/reporter as dependency of your custom reporter:

npm install @wdio/reporter

or

yarn add @wdio/reporter

Then you need to extend your reporter with the main @wdio/reporter class:

import Reporter from '@wdio/reporter'

export default MyCustomReporter extends Reporter {
    constructor () {
        super()
        // your custom logic if necessary
        // ...
    }

    onRunnerStart () {
        // ...
    }

    onSuiteStart (suite) {
        // ...
    }

    // ...
}

The Reporter parent class calls your event functions if provided when an event was triggered and provides information on that event in a consistent format. You can always register your own listener to receive the raw data that was provided by the framework, e.g. instead of using the onSuiteStart method you can do:

this.on('suite:start', (raw) => {
    // ...
})

in your constructor function.

Configuration

User can pass in custom configurations for each reporter. Per default WebdriverIO populates the outputDir and logLevel option to the reporter, they can get overwritten too. For example, if the user has provided the following reporter options:

// wdio.conf.js
exports.config = {
    // ...
    reporters: ['dot', ['my-reporter', {
        outputDir: '/some/path',
        foo: 'bar'
    }]]
    // ...
}

your options in your reporter class are as follows:

export default class MyReporter extends Reporter {
    constructor () {
        super()
        console.log(this.options)
        /**
         * outputs:
         * {
         *   outputDir: '/some/path',
         *   logLevel: 'trace',
         *   foo: 'bar'
         * }
         */
    }
}

You can access all options via this.options. You can push logs to stdout or a log file depending of whether the stdout option is true or false. Please use the internal method write that is provided by the Reporter parent class in order to push out logs, e.g.

class MyReporter extends Reporter {
    constructor (options) {
        /**
         * make dot reporter to write to output stream by default
         */
        options = Object.assign(options, { stdout: true })
        super(options)
    }

    // ...
    onTestPass (test) {
        this.write(`test "${test.title}" passed`)
    }
    // ...
}

This will result the following output:

"MyReporter" Reporter:
test "some test" passed
test "some other test" passed

"spec" Reporter:
...

If stdout is set to false WebdriverIO will automatically write to a filestream at a location where other logs are stored as well.

Synchronization

If your reporter needs to do some async computation after the test (e.g. upload logs to a server) you can overwrite the isSynchronised getter method to manage this. By default this property always returns true as most of the reporters don't require to do any async work. However in case you need to handle this overwrite the getter method with an custom implementation (e.g. wdio-sumologic-reporter).

class MyReporter extends Reporter {
    constructor (options) {
        // ...
    }

    get isSynchronised (test) {
        return this.unsyncedMessages.length === 0
    }

    // ...
}

The wdio testrunner will wait to kill the runner process until every reporter has the isSynchronised property set to true.

Events

During a test run in WebdriverIO several events are thrown and can be captured by your event functions. The following events are propagated:

Test Events

These events are containing data about the test regardless of the framework it is running in.

onSuiteStart
SuiteStats {
  type: 'suite',
  start: '2018-02-09T13:30:40.177Z',
  duration: 0,
  uid: 'root suite2',
  cid: '0-0',
  title: 'root suite',
  fullTitle: 'root suite',
  tests: [],
  hooks: [],
  suites: [] } }
onSuiteEnd
SuiteStats {
  type: 'suite',
  start: '2018-02-09T13:30:40.177Z',
  duration: 1432,
  uid: 'root suite2',
  cid: '0-0',
  title: 'root suite',
  fullTitle: 'root suite',
  tests: [ [TestStats] ],
  hooks: [ [HookStats], [HookStats] ],
  suites: [ [Object] ],
  end: '2018-02-09T13:30:41.609Z' } }
onSuiteRetry

(Cucumber only)

SuiteStats {
  start: 2024-11-13T06:33:21.499Z,
  end: undefined,
  type: 'scenario',
  uid: '0',
  cid: '0-0',
  file: '/Users/christian.bromann/Sites/WebdriverIO/projects/webdriverio/examples/wdio/cucumber/features/my-feature.feature',
  title: 'Get size of an element',
  fullTitle: 'my-feature.feature:1:1: Get size of an element',
  tags: [],
  tests: [],
  hooks: [],
  suites: [],
  parent: 'my-feature.feature:1:1',
  retries: 1,
  hooksAndTests: [],
  description: '',
  rule: undefined
}
onHookStart
HookStats {
  type: 'hook',
  start: '2018-02-09T13:30:40.181Z',
  duration: 0,
  uid: '"before each" hook4',
  cid: '0-0',
  title: '"before each" hook',
  parent: 'root suite',
onHookEnd
HookStats {
  type: 'hook',
  start: '2018-02-09T13:30:40.181Z',
  duration: 1,
  uid: '"before each" hook4',
  cid: '0-0',
  title: '"before each" hook',
  parent: 'root suite',
  end: '2018-02-09T13:30:40.182Z' } }
onTestStart
TestStats {
  type: 'test',
  start: '2018-02-09T13:30:40.180Z',
  duration: 0,
  uid: 'passing test3',
  cid: '0-0',
  title: 'passing test',
  fullTitle: 'passing test',
  retries: 0,
  state: 'pending' } }

Cucumber tests come with an additional argument property containing data tables if used in feature files, e.g.:

TestStats {
  type: 'test',
  start: '2019-07-08T08:44:56.666Z',
  duration: 0,
  uid: 'I add the following grocieries16',
  cid: '0-0',
  title: 'I add the following grocieries',
  output: [],
  argument: [{
    rows: [{
      cells: ['Item', 'Amount'],
      locations: [{
        line: 17,
        column: 11
      }, {
        line: 17,
        column: 24
      }]
    }, {
      cells: ['Milk', '2'],
      locations: [{
        line: 18,
        column: 11
      }, {
        line: 18,
        column: 24
      }]
    }, {
      cells: ['Butter', '1'],
      locations: [{
        line: 19,
        column: 11
      }, {
        line: 19,
        column: 24
      }]
    }, {
        cells: ['Noodles', '1'],
      locations: [{
        line: 20,
        column: 11
      }, {
        line: 20,
        column: 24
      }]
    }, {
      cells: ['Schocolate', '3'],
      locations: [{
        line: 21,
        column: 11
      }, {
        line: 21,
        column: 24
      }]
    }]
  }],
  state: 'pending'
}
onTestSkip
TestStats {
  type: 'test',
  start: '2018-02-09T14:01:04.573Z',
  duration: 0,
  uid: 'skipped test6',
  cid: '0-0',
  title: 'skipped test',
  fullTitle: 'skipped test',
  retries: 0,
  state: 'skipped' }
onTestPass
TestStats {
  type: 'test',
  start: '2018-02-09T14:11:28.075Z',
  duration: 1503,
  uid: 'passing test3',
  cid: '0-0',
  title: 'passing test',
  fullTitle: 'passing test',
  retries: 0,
  state: 'passed',
  end: '2018-02-09T14:11:29.578Z' } }
onTestRetry
TestStats {
  type: 'test',
  start: 2020-09-23T07:54:34.601Z,
  _duration: 2495,
  uid: 'test-00-0',
  cid: '0-0',
  title: 'test fails and retries',
  fullTitle: 'test fails and retries',
  retries: 0,
  state: 'failed',
  end: 2020-09-23T07:54:37.096Z,
  error:
      { message: 'some error',
        stack: `Error: some error\n    at Context.it (/path/to/project/test/b.js:17:19)\n
  at /path/to/project/packages/wdio-sync/src/index.js:490:28\n    at Promise (<anonymous>)\
n    at F (/path/to/project/node_modules/core-js/library/modules/_export.js:35:28)\n    at
Context.executeSync (/path/to/project/packages/wdio-sync/src/index.js:488:12)\n    at /path/to/project/packages/wdio-sync/src/index.js:623:33`,
        type: 'Error' } } }
onTestFail
TestStats {
     type: 'test',
     start: '2018-02-09T14:11:29.581Z',
     duration: 21,
     uid: 'failing test8',
     cid: '0-0',
     title: 'failing test',
     fullTitle: 'failing test',
     retries: 0,
     state: 'failed',
     end: '2018-02-09T14:11:29.602Z',
     error:
      { message: 'some error',
        stack: `Error: some error\n    at Context.it (/path/to/project/test/b.js:17:19)\n
  at /path/to/project/packages/wdio-sync/src/index.js:490:28\n    at Promise (<anonymous>)\
n    at F (/path/to/project/node_modules/core-js/library/modules/_export.js:35:28)\n    at
Context.executeSync (/path/to/project/packages/wdio-sync/src/index.js:488:12)\n    at /path/to/project/packages/wdio-sync/src/index.js:623:33`,
        type: 'Error' } } }
onTestEnd
TestStats {
  type: 'test',
  start: '2018-02-09T14:11:28.075Z',
  duration: 1503,
  uid: 'passing test3',
  cid: '0-0',
  title: 'passing test',
  fullTitle: 'passing test',
  retries: 0,
  state: 'passed',
  end: '2018-02-09T14:11:29.578Z' } }

Runner Events

These events contain information on the test runner.

onRunnerStart
RunnerStats {
  type: 'runner',
  start: '2018-02-09T14:30:19.871Z',
  duration: 0,
  cid: '0-0',
  capabilities:
   { acceptInsecureCerts: false,
     browserName: 'firefox',
     browserVersion: '59.0',
     'moz:accessibilityChecks': false,
     'moz:headless': false,
     'moz:processID': 92113,
     'moz:profile': '/var/folders/ns/8mj2mh0x27b_gsdddy1knnsm0000gn/T/rust_mozprofile.jlpfs632Becb',
     'moz:webdriverClick': true,
     pageLoadStrategy: 'normal',
     platformName: 'darwin',
     platformVersion: '17.3.0',
     rotatable: false,
     timeouts: { implicit: 0, pageLoad: 300000, script: 30000 } },
  sanitizedCapabilities: 'firefox.59_0.darwin',
  config: [Object],
  specs: [ '/path/to/project/test/my.test.js' ] },
  retry: 0
onRunnerEnd
RunnerStats {
  type: 'runner',
  start: '2018-02-09T14:30:19.871Z',
  duration: 1546,
  uid: undefined,
  cid: '0-0',
  capabilities: [Object],
  sanitizedCapabilities: 'firefox.59_0.darwin',
  config: [Object],
  specs: [ '/path/to/project/test/my.test.js' ],
  failures: 1,
  retries: 1,
  end: '2018-02-09T14:30:21.417Z' } }

Client Events

Client events are triggered when certain interactions with the automation driver are happening.

onBeforeCommand
{ method: 'GET',
  endpoint: '/session/:sessionId/element',
  body: { using: 'css selector', value: 'img' }
  cid: '0-0',
  sessionId: '4d1707ae-820f-1645-8485-5a820b2a40da',
  capabilities: [Object] }
onAfterCommand
{ method: 'GET',
  endpoint: '/session/:sessionId/element/fbf57b79-6521-7d49-b3b7-df91cf2c347a/rect',
  body: {},
  result: { value: { x: 75, y: 11, width: 160, height: 160 } },
  cid: '0-0',
  sessionId: '4d1707ae-820f-1645-8485-5a820b2a40da',
  capabilities: [Object] }