Skip to content

feat(providers): add TestingBot cloud provider#118

Merged
Winify merged 4 commits into
webdriverio:mainfrom
testingbot:feature/testingbot-integration
Jun 9, 2026
Merged

feat(providers): add TestingBot cloud provider#118
Winify merged 4 commits into
webdriverio:mainfrom
testingbot:feature/testingbot-integration

Conversation

@jochen-testingbot

@jochen-testingbot jochen-testingbot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

Adds TestingBot as a cloud provider, at feature parity with the existing BrowserStack, Sauce Labs, and TestMu integrations. It slots into the established SessionProvider pattern (src/providers/) — one provider class plus the usual enum/dispatch widening — and follows the same shape as the TestMu integration in #116.

New Provider (src/providers/cloud/testingbot.provider.ts)

TestingBotProvider implements the SessionProvider interface with three capability modes (browser, mobile browser/emulator, mobile native app), tunnel lifecycle via testingbot-tunnel-launcher, and session result reporting via the TestingBot REST API. Uses TESTINGBOT_KEY / TESTINGBOT_SECRET environment variables (mapped to WebDriver user/key); credentials never appear in tool call parameters. Hub: hub.testingbot.com, capability block tb:options.

App Management (src/tools/cloud-provider.tool.ts)

  • list_apps for TestingBot fetches GET /v1/storage (single call — no per-platform split needed) and returns tb:// refs.
  • upload_app uploads to POST /v1/storage (multipart field file), returns the tb:// app URL for use in start_session.

Result Marking

PUT https://api.testingbot.com/v1/tests/:id with form-encoded test[success]=1|0. A single code path covers both web and mobile sessions — the :id route accepts the WebDriver session UUID, so there's no web-REST / mobile-execute split.

Tunnel Binary Resource (src/resources/testingbot-local.resource.ts)

wdio://testingbot/local-binary resource with the TestingBot Tunnel download URL and setup commands, matching the BrowserStack/Sauce Labs/TestMu pattern. Note: the TestingBot Tunnel is a single cross-platform Java JAR (requires Java 11+) rather than per-platform native binaries.

Also adds tb:options detection to the code generator (wdio://session/current/code), a type shim for the untyped testingbot-tunnel-launcher package, and README/CLAUDE.md documentation.

Types of changes

  • Polish (an improvement for an existing feature)
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update (improvements to the project's docs)
  • Specification changes (updates to WebDriver command specifications)
  • Internal updates (everything related to internal scripts, governance documentation and CI files)

Checklist

  • I have squashed commits that belong together
  • I have tested with Claude (or another MCP-compatible client)
  • I have read the CONTRIBUTING doc
  • I have added the necessary documentation for new/changed tools (if appropriate)
  • I have added proper type definitions for new commands (if appropriate)

Further comments

Testing: npm test passes (411 tests across 30 files), including a new testingbot.provider.test.ts suite plus registry and cloud-tool cases. npm run lint is clean (0 errors) and npm run bundle builds. A live end-to-end browser session against a real TestingBot account was run and verified (session and pass/fail result confirmed on the TestingBot dashboard).

Design notes:

  • Credentials use TestingBot's native TESTINGBOT_KEY / TESTINGBOT_SECRET naming (matches TestingBot docs and the @wdio/testingbot-service convention) rather than the *_USERNAME / *_ACCESS_KEY shape of the other providers.
  • Browser sessions default platformName to Windows 11 when os is omitted (TestingBot's most broadly available platform); overridable via os / osVersion.
  • No deprecated testingbotLocal alias was added — this is a new provider, so it uses only the unified tunnel parameter.

Reviewers: @webdriverio/project-committers

Adds TestingBot at parity with BrowserStack, Sauce Labs, and TestMu:
browser + mobile sessions, auto-start tunnel via testingbot-tunnel-launcher,
upload_app/list_apps through TestingBot Storage, pass/fail result marking,
generated reproduction code, and the wdio://testingbot/local-binary resource.

Credentials: TESTINGBOT_KEY / TESTINGBOT_SECRET.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds TestingBot as a fourth cloud provider, slotting into the established SessionProvider pattern with feature parity to BrowserStack, Sauce Labs, and TestMu — covering browser, mobile browser/emulator, and native app sessions, tunnel lifecycle, app storage, and session result marking.

  • New provider (src/providers/cloud/testingbot.provider.ts): implements buildCapabilities for three session modes, startTunnel/stopTunnel via testingbot-tunnel-launcher, and onSessionClose result marking via PUT /v1/tests/:id with form-encoded test[success].
  • Tool widening (cloud-provider.tool.ts, session.tool.ts): list_apps, upload_app, and start_session enums extended to include testingbot; parseListResponse/parseUploadResponse added with correct null guards.
  • Code generator + resource (code-generator.ts, testingbot-local.resource.ts): tb:options detection added for generated session scripts; new wdio://testingbot/local-binary resource documents the cross-platform Java JAR tunnel.

Confidence Score: 5/5

Safe to merge — the change is purely additive, follows the existing provider pattern faithfully, and carries comprehensive unit test coverage.

The provider correctly handles all three session modes, tunnel lifecycle uses close() on the specific handle (not a global kill), and the result-marking path is well-tested. Two style-level items were found in the generated code (unused tunnel variable) and provider (dead testingbotLocal fallback), neither of which affects runtime correctness.

No files require special attention. The two findings in code-generator.ts and testingbot.provider.ts are clean-up items with no functional impact.

Important Files Changed

Filename Overview
src/providers/cloud/testingbot.provider.ts New TestingBotProvider implementing all three capability modes. stopTunnel correctly uses close() callback. Dead-code nit: options.testingbotLocal in buildCapabilities is never populated.
src/recording/code-generator.ts TestingBot code generation added. The tunnel variable from downloadAndRunAsync is unused because stopTunnel calls killAsync() instead of tunnel.close().
src/tools/cloud-provider.tool.ts TestingBot config block added with correct null guards. Enum widening is consistent.
src/resources/testingbot-local.resource.ts Resource definition for wdio://testingbot/local-binary following the established pattern.
src/types/testingbot-tunnel-launcher.d.ts Type shim for untyped testingbot-tunnel-launcher package. Accurately models the API.
tests/providers/testingbot.provider.test.ts Comprehensive unit tests covering all three capability modes, tunnel lifecycle, and error paths.
tests/tools/cloud-provider.tool.test.ts TestingBot list/upload tests added covering success, response parsing, and missing-credentials error path.

Sequence Diagram

sequenceDiagram
    participant Client as MCP Client
    participant SessionTool as start_session tool
    participant Registry as providers/registry.ts
    participant TBProvider as TestingBotProvider
    participant TBTunnel as testingbot-tunnel-launcher
    participant TBAPI as api.testingbot.com
    participant Hub as hub.testingbot.com

    Client->>SessionTool: "start_session({ provider: 'testingbot', tunnel: true, ... })"
    SessionTool->>Registry: getProvider('testingbot', platform)
    Registry-->>SessionTool: TestingBotProvider
    SessionTool->>TBProvider: buildCapabilities(options)
    TBProvider-->>SessionTool: "{ browserName, platformName, tb:options, ... }"
    SessionTool->>TBProvider: startTunnel(options)
    TBProvider->>TBTunnel: "downloadAndRunAsync({ apiKey, apiSecret, tunnelIdentifier })"
    TBTunnel-->>TBProvider: tunnelHandle
    TBProvider-->>SessionTool: tunnelHandle
    SessionTool->>Hub: POST /wd/hub (WebDriver session with capabilities)
    Hub-->>SessionTool: sessionId

    Note over Client,Hub: Session active — test steps execute

    Client->>SessionTool: "close_session({ status: 'passed' })"
    SessionTool->>TBProvider: onSessionClose(sessionId, type, result)
    TBProvider->>TBAPI: "PUT /v1/tests/:sessionId (test[success]=1)"
    TBAPI-->>TBProvider: 200 OK
    SessionTool->>TBProvider: stopTunnel(tunnelHandle)
    TBProvider->>TBTunnel: tunnel.close(callback)
    TBTunnel-->>TBProvider: callback()
Loading

Reviews (2): Last reviewed commit: "fix(testingbot): make tunnel-already-run..." | Re-trigger Greptile

Comment thread src/tools/cloud-provider.tool.ts
Comment thread src/providers/cloud/testingbot.provider.ts Outdated
Comment thread src/providers/cloud/testingbot.provider.ts Outdated

@Winify Winify left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved 🎉 publishing this as 3.7.0

@Winify Winify merged commit 34e6f37 into webdriverio:main Jun 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants