The Tesults web app is designed for desktop browsers. Sign up and configure your project on a laptop or desktop. Use the iOS app or Android app to view results on the go.

How to Report WebdriverIO Test Results to a Dashboard

Send WebdriverIO results somewhere durable and team-visible using the Tesults service, with the wdio.conf.js setup, enhanced reporting, and parallel run consolidation

blog-title-image

WebdriverIO gives you a capable test runner, but its output lives with the run, so once a team has more than one wdio suite or more than one person who needs to see results, the console stops being enough. To report WebdriverIO results to a dashboard, add the Tesults service to your wdio.conf.js and pass a target token. Each run then pushes to Tesults, where suites and cases are retained across runs and consolidated across parallel workers. WebdriverIO integrates through a service rather than a plain reporter, so the setup sits in the services array of your config. This post coversthat setup, the enhanced reporting functions, and consolidating parallel runs.

How do you add the Tesults service?

Install it. Note the package is wdio-tesults-service, which is the current, supported integration. The older wdio-tesults-reporter has been deprecated and should not be used:

npm install wdio-tesults-service --save

It requires Node.js 14 or newer and works with WebdriverIO using the Mocha, Jasmine, and Cucumber frameworks. Add the service to the services array in your wdio.conf.js, with the options object carrying your target token:

exports.config = {
  // ...
  services: [
    ['tesults',
      {
        target: 'token'
      }
    ]
  ],
  // ...
}

Replace token with your Tesults target token, which you get when creating a project or target and can regenerate from the configuration menu. The target is required: if it is not provided, the service doesnot attempt to upload, effectively disabling itself. That behavior is useful, because it lets the same config stay inert locally and active in CI. Run your tests as usual:

npx wdio run ./wdio.conf.js

At this point results upload to Tesults. To report to different targets without maintaining multiple config files, pass the token from a variable set by a command line argument or your CI system rather than hardcoding it:

const target = () => { // target token from commandline arg }
exports.config = {
  // ...
  services: [
    ['tesults',
      {
        target: target()
      }
    ]
  ],
  // ...
}

How do you add descriptions, steps, and files to a case?

Beyond pass and fail, you can attach a description, custom fields, test steps, and files to each case. Require the service in your spec file:

const tesultsService = require('wdio-tesults-service').default

Then call its functions from inside a test:

const tesultsService = require('wdio-tesults-service').default

describe('Test suite', () => {
  it('Test case', async () => {
    tesultsService.description("some description here")
    tesultsService.custom("Some custom field", "Some custom value")
    tesultsService.step({
      name: "First step",
      result: "pass"
    })
    tesultsService.step({
      name: "Second step",
      description: "Second step description",
      result: "fail",
      reason: "Error line 203 of test.js"
    })
    tesultsService.file("/absolute/path/to/file/screenshot.png")
  });
});

Steps are the field that most changes what a failure looks like. Each step is an object with a name and a result of pass, fail, or unknown, plusoptional description and reason. Instead of a case that simply failed, you get the sequence that led there with the failing step and a reason, which is the difference between knowing a test failed and knowing where. On files, one caution from the docs: upload time depends entirely on your network speed and the upload blocks at the end of the run, so attach a reasonable number of files per case, and when first integrating, get results flowing without files to confirm the setup before adding them.

How do you report build information?

You can attach build details to a run by passing a build object in theservice options in wdio.conf.js, which is useful when the run is part of a CI pipeline:

exports.config = {
  // ...
  services: [
    ['tesults',
      {
        target: 'token',
        build: {
          name: '1.0.0',
          result: 'pass',
          description: 'build description',
          reason: 'build failure reason'
        }
      }
    ]
  ],
  // ...
}

All build fields are optional. The result must be one of pass, fail, or unknown, and the reason records why a build failed. This is context worth having when looking back at a run later.

How do you consolidate parallel runs into one result?

WebdriverIO commonly runs specs in parallel across multiple workers, and teams often shard suites across CI machines too. Each submission is treated as its own run by default, so parallel execution produces several runs for what you think of as one. To merge them, give every submission for the same logical run a shared build name, then enable Build Consolidation from the configuration menu. Submissions sharing a build name are consolidated into a single run automatically. If there is no natural version to useas the build name, a timestamp captured when the run starts works as the shared identifier.

There is also an optional Build Replacement setting that, when enabledalongside consolidation, replaces an existing case with the same suite and name rather than appending it. That is worth enabling only if you frequently re-run cases within the same build and want only the latest result; otherwise leave it off.

How do you keep results comparable across runs?

Retained results are only useful if each test is recognisable as the same test from one run to the next. Tesults matches cases across runs by suite and test name, so with data driven wdio tests, keep the suite and testnames static and put variable values in the description or a custom field. If the name changes every run, each run looks like a fresh set of tests and you lose historical analysis and failure assignment. Your tests stay as dynamic as you like; only the identifier stays fixed.

Once runs are retained and aligned, each WebdriverIO test carries a history rather than a single outcome, so you can see which cases just started failing, which have been flaky, and how pass rate is trending, none of which the console output can tell you. That history is also what lets Tesults surface flaky wdio tests automatically, which matters because browser and end to end tests are especially prone to flakiness. The broader approach is covered in how to detect and handle flaky tests.

The whole change is one install and a small addition to your wdio.conf.js, and it leaves how you write and run WebdriverIO tests untouched. Whatyou get back is results that outlive the console, are visible to the whole team, and consolidate across parallel workers into one history you can act on. Full configuration, enhanced reporting, and build options are documented in the Tesults WebdriverIO documentation.

Test automation reporting and failure intelligence

Consolidated test reporting for engineering teams. Store, track, and understand test results across every run and system.

Latest Posts

How to Report WebdriverIO Test Results to a Dashboard
How to Report WebdriverIO Test Results to a Dashboard
Send WebdriverIO results somewhere durable and team-visible using the Tesults service, with the wdio.conf.js setup, enhanced reporting, and parallel run consolidation
How to Report Cypress Test Results to a Dashboard
How to Report Cypress Test Results to a Dashboard
Send Cypress results somewhere durable and team-visible using the Cypress Module API, with screenshots and videos attached and runs consolidated across CI
Why Playwright Tests Pass Locally but Fail in CI
Why Playwright Tests Pass Locally but Fail in CI
The real reasons Playwright tests go green on your machine and red in CI, how to debug each one, and how to tell a genuine failure from an environment flake
How to Detect and Handle Flaky Tests
How to Detect and Handle Flaky Tests
What makes a test flaky, how to detect flaky tests automatically instead of by memory, and how to handle them without disabling coverage
How to Report Vitest Test Results to a Dashboard
How to Report Vitest Test Results to a Dashboard
Send Vitest results somewhere durable and team-visible, with the setup details specific to Vitest, so multiple test jobs consolidate into one history you can act on
How to Report Go Test Results to a Dashboard
How to Report Go Test Results to a Dashboard
Go has no reporter plugin, so reporting go test results means parsing go test -json and uploading the cases yourself. Here is the whole pattern.
How to Report Jest Test Results to a Dashboard
How to Report Jest Test Results to a Dashboard
How to send Jest results somewhere they are kept, viewable by the team, and comparable across runs, without giving up the default reporter
How to View Playwright Test Results in CI
How to View Playwright Test Results in CI
How to get Playwright results out of the CI console and into a durable dashboard, including parallel shards, screenshots, and retained history
What Is a Test Results Dashboard and When Do You Need One
What Is a Test Results Dashboard and When Do You Need One
What a test results dashboard actually does, how it differs from your CI logs and your test framework report, and the point at which a team starts needing one
Diagnosing CI Failures Automatically With an AI Failure Diagnosis API
Diagnosing CI Failures Automatically With an AI Failure Diagnosis API
How to turn a red build into a root cause, a regression list, and a deploy gate without a human reading the logs
How AI Coding Agents Use Test Results to Verify Their Own Work
How AI Coding Agents Use Test Results to Verify Their Own Work
Why a raw pass or fail is not enough for an agent to trust its own change, and how failure intelligence closes the self-verification loop
Store and View Pytest Results Over Time
Store and View Pytest Results Over Time
Why pytest results vanish after each CI run, and how to keep a durable history you can view, compare, and track over time