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

@tvlabs/wdio-service

v0.1.11

Published

WebdriverIO service that provides a better integration into TV Labs

Readme

Introduction

npm

The @tvlabs/wdio-service package uses a websocket to connect to the TV Labs platform before an Appium session begins, logging events relating to build upload and session creation as they occur. This offloads the responsibility of creating the TV Labs session from the POST /session Webdriver endpoint, leading to more reliable session requests and creation.

If a build path is provided, the service first makes a build upload request to the TV Labs platform, and then sets the tvlabs:build capability to the newly created build ID.

The service then makes a session request and then subscribes to events for that request. Once the session has been filled and is ready for the Webdriver script to begin, the service receives a ready event with the TV Labs session ID. This session ID is injected into the capabilities as tvlabs:session_id on the Webdriver session create request.

Additionally, the service automatically injects an Authorization header with your API key (formatted as Bearer ${apiKey}) into all requests to the TV Labs platform. If you have already set an Authorization header in your configuration, the service will respect your existing header and not override it.

The service also adds a unique request ID for each request made. The service will generate and attach an x-request-id header before each request to the TV Labs platform. This can be used to correlate requests in the client side logs to the Appium server logs.

Installation

In your WebdriverIO project, run one of the following commands to install:

NPM

npm i --save @tvlabs/wdio-service

Yarn

yarn add @tvlabs/wdio-service

Usage

WebdriverIO Test Runner

To use this as a WebdriverIO test runner service, include the service in your WebdriverIO configuration file (e.g. wdio.conf.ts) with your TV Labs API key set in the options.

import { TVLabsService } from '@tvlabs/wdio-service';

export const config = {
  // ...
  services: [[TVLabsService, { apiKey: process.env.TVLABS_API_KEY }]],
  // ...
};

WebdriverIO Remote

To use this with WebdriverIO remote but without the test runner, call the beforeSession hook before instantiating the remote.

import { remote } from 'webdriverio';
import { TVLabsService } from '@tvlabs/wdio-service';

async function run() {
  const capabilities = { ... };

  const wdOpts = {
    capabilities,
    hostname: 'appium.tvlabs.ai',
    port: 4723
  };

  const serviceOpts = {
    apiKey: process.env.TVLABS_API_TOKEN,
  }

  // NOTE: it is important to make sure that
  // the wdOpts passed here are the same reference
  // as the one passed to remote()
  const service = new TVLabsService(serviceOpts, capabilities, wdOpts)

  // The TV Labs service does not use specs or a cid, pass default values.
  const cid = ""
  const specs = []

  await service.beforeSession(wdOpts, capabilities, specs, cid)

  const driver = await remote(wdOpts);

  try {
    // ...
  } finally {
    await driver.deleteSession();
  }
}

run();

Options

apiKey

  • Type: string
  • Required: Yes
  • Description: TV Labs API key used for authentication to the platform

buildPath

  • Type: string
  • Required: No
  • Description: Path to the packaged build to use for the session. When provided, this will perform a build upload before the session is created, and sets the tvlabs:build capability to the newly created build ID. The build is uploaded under the organizations default App unless the app option is provided

app

  • Type: string
  • Required: No
  • Description: The slug of the app on the TV Labs platform to use to upload the build. When not provided, the organization's default app is used. You may find or create an app on the Apps page in the TV Labs platform.

retries

  • Type: number
  • Required: No
  • Default: 3
  • Description: Maximum number of attempts to create a session before failing

reconnectRetries

  • Type: number
  • Required: No
  • Default: 5
  • Description: Maximum number of attempts to re-connect if the connection to TV Labs is lost.

attachRequestId

  • Type: boolean
  • Required: No
  • Default: true
  • Description: Controls whether or not to attach an x-request-id header to each request made to the TV Labs platform.

continueOnError

  • Type: boolean
  • Required: No
  • Default: false
  • Description: Whether to continue the session request if any step fails. When true, the session request will still be made with the original provided capabilities. When false, the service will exit with a non-zero code.

Methods

lastRequestId()

  • Returns: string | undefined
  • Description: Returns the last request ID that was attached to a request made to the TV Labs platform. This is useful for correlating client-side logs with server-side logs. Returns undefined if no request has been made yet or if attachRequestId is set to false.

Example

import { remote } from 'webdriverio';
import { TVLabsService } from '@tvlabs/wdio-service';

const capabilities = { ... };
const wdOpts = { ... };

const service = new TVLabsService(
  { apiKey: process.env.TVLABS_API_KEY },
  capabilities,
  wdOpts
);

await service.beforeSession(wdOpts, capabilities, [], '');

const driver = await remote(wdOpts);

// Get the last request ID
const requestId = service.lastRequestId();
console.log(`Last request ID: ${requestId}`);

requestMetadata()

  • Parameters: appiumSessionId: string, requestIds: string | string[]
  • Returns: Promise<TVLabsRequestMetadata | TVLabsRequestMetadataResponse>
  • Description: Fetches metadata for one or more Appium request IDs from the TV Labs platform. If a single request ID is provided, returns the metadata for that request. If an array of request IDs is provided, returns a map where keys are request IDs and values are their corresponding metadata.

Note: Request metadata is processed asynchronously on the TV Labs platform. To ensure metadata is available, it is recommended to fetch request metadata a few seconds after the request, or after the session has ended.

Example

import { remote } from 'webdriverio';
import { TVLabsService } from '@tvlabs/wdio-service';

const capabilities = { ... };
const wdOpts = { ... };

const service = new TVLabsService(
  { apiKey: process.env.TVLABS_API_KEY },
  capabilities,
  wdOpts
);

await service.beforeSession(wdOpts, capabilities, [], '');

const driver = await remote(wdOpts);
let requestId;

try {
  // Perform some actions that generate requests
  const element = await driver.$('#my-button');
  await element.click();

  // Get the request ID from the click
  requestId = service.lastRequestId();
  console.log(`Request ID: ${requestId}`);
} finally {
  await driver.deleteSession();
}

// Fetch metadata after session ends (recommended)
if (requestId) {
  const metadata = await service.requestMetadata(driver.sessionId, requestId);
  console.log('Request metadata:', metadata);
}

// Fetch metadata for multiple requests
const multiMetadata = await service.requestMetadata("appium-session-id-1234"[
  'request-id-123',
  'request-id-456',
  'request-id-789'
]);

console.log('Multiple requests metadata:', multiMetadata);