Features

TestingBot GitHub Action

This guide will help you integrate the TestingBot GitHub Action workflow in your project.
The TestingBot GitHub action provides an action to integrate the TestingBot Tunnel in your tests.
The TestingBot Tunnel is used to route all test traffic between your web application and the TestingBot browser/device cloud.

The GitHub action will also save the test-artifacts for you, so that you can later see the meta-data generated by the test.

GitHub Secrets

To get started, you'll need to configure 2 secrets in your GitHub repository.
These 2 secrets are TB_KEY (your TestingBot Key) and TB_SECRET (TestingBot secret) which can be obtained from the TestingBot member area.

In your GitHub repository, go to Settings and find the Secrets option in the left-hand pane.

Add both the TB_KEY and TB_SECRET as Repository Secrets:

GitHub Secrets

Set up a GitHub workflow

Next, we'll create a new GitHub workflow. Create a workflow file test-workflow.yml in the .github/workflows directory of your GitHub repository.
You can find out more about workflow files on the GitHub documentation pages.

In your workflow file, you can indicate when to run the GitHub Action.
We recommend doing this on both push and pull_request for maximum test coverage:

name: "TestingBot Test"
on: [push, pull_request]

jobs:
    test:
        runs-on: ubuntu-latest
        name: Sample Test
...

You can specify a runs-on parameter, to indicate the OS of the container that should run your test.

The most important part is the steps section, which we'll cover in the example below.

Example workflow with TestingBot

Let's set up a workflow that will do the following actions:

  • Checkout the current GitHub repository code
  • Install dependencies for the project
  • Run the tests in the repository
name: "PR Checks"
on: push

jobs:
    test:
        runs-on: ubuntu-latest
        name: Action Test
        steps:
            - uses: actions/checkout@v1
            - uses: testingbot/testingbot-tunnel-action@v1
              with:
                key: ${{ secrets.TB_KEY }}
                secret: ${{ secrets.TB_SECRET }}
                tunnelIdentifier: github-action-tunnel

            - name: "Install Dependencies"
              run: npm install

            - name: "Run Test"
              run: npm run test
              env:
                TB_KEY: ${{ secrets.TB_KEY }}
                TB_SECRET: ${{ secrets.TB_SECRET }}

Here we're including the testingbot/testingbot-tunnel-action TestingBot GitHub action with a key, secret and tunnelIdentifier.

The tunnelIdentifier is used to indicate in your tests that a connection should be made to this specific tunnel.

Example Test

For example, let's say your npm run test starts a local http-server and then runs a Selenium WebDriver test:

http-server ./test -p 8080 > /dev/null 2>&1 &
#!/usr/bin/env ruby

require 'rubygems'
require 'selenium-webdriver'

caps = Selenium::WebDriver::Remote::Capabilities.new
caps["browserName"] = "chrome"
caps["version"] = "latest"
caps["platform"] = :WINDOWS
caps["name"] = "GitHub Action Test"
caps["tunnel-identifier"] = "github-action-tunnel"

client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 120

driver = Selenium::WebDriver.for(
	:remote,
	:url => "https://#{ENV['TB_KEY']}:#{ENV['TB_SECRET']}@hub.testingbot.com/wd/hub",
	:desired_capabilities => caps,
	:http_client => client)
driver.navigate.to "http://localhost:8080"
puts driver.title
driver.quit
import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.net.URL;

public class AccessibilityTest {

  public static final String KEY = System.getenv("TB_KEY");
  public static final String SECRET = System.getenv("TB_SECRET");
  public static final String URL = "http://" + KEY + ":" + SECRET + "@hub.testingbot.com/wd/hub";

  public static void main(String[] args) throws Exception {

	DesiredCapabilities caps = new DesiredCapabilities();
	caps.setCapability("browserName", "chrome");
	caps.setCapability("version", "latest-1");
	caps.setCapability("platform", "WIN10");
	caps.setCapability("name", "GitHub Action Test");
	caps.setCapability("tunnel-identifier", "github-action-tunnel");

	WebDriver driver = new RemoteWebDriver(new URL(URL), caps);
	driver.get("http://localhost:8080");

	System.out.println(driver.getTitle());

	driver.quit();
  }
}
<?php

    require_once('vendor/autoload.php');
    use Facebook\WebDriver\Remote\RemoteWebDriver;
    use Facebook\WebDriver\WebDriverBy;

    $tbKey = getenv('TB_KEY');
    $tbSecret = getenv('TB_SECRET');

    $web_driver = RemoteWebDriver::create(
    "https://$tbKey:$tbSecret@hub.testingbot.com/wd/hub",
        array("platform"=>"WIN10", "browserName"=>"chrome", "version" => "latest", "name" => "GitHub Action Test"), 120000
    );
    $web_driver->get("http://localhost:8080");
    echo $web_driver->getTitle();
    $web_driver->quit();
?>
from selenium import webdriver
desired_cap = {
	'platform': 'WIN10', 
	'browserName': 'chrome', 
	'version': 'latest-1',
	'name': 'GitHub Action Test'
}
tbKey = os.environ['TB_KEY']
tbSecret = os.environ['TB_SECRET']
driver = webdriver.Remote(
    desired_capabilities=desired_cap,
    command_executor='https://' + tbKey + ':' + tbSecret + '@hub.testingbot.com/wd/hub',
    )
driver.get("http://localhost:8080")
print(driver.title)
driver.quit()
const webdriver = require('selenium-webdriver');
const fs = require('fs')

const testingbotKey = process.env.TB_KEY;
const testingbotSecret = process.env.TB_SECRET;

const capabilities = {
    'browserName': 'firefox',
    'platform': 'WIN10',
    'version': 'latest',
    'client_key': testingbotKey,
    'client_secret': testingbotSecret,
    'name': 'GitHub Action Test'
};

async function runGitHubActionTest () {
  let driver = new webdriver.Builder()
    .usingServer('https://' + testingbotKey + ':' + testingbotSecret + '@hub.testingbot.com/wd/hub')
    .withCapabilities(capabilities)
    .build();
  await driver.get("http://localhost:8080");
  const title = await driver.getTitle();
  console.log(title)
  await driver.quit();
}
runGitHubActionTest();
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;

namespace SeleniumTest {
  class Program {
    static void Main(string[] args) {
      IWebDriver driver;
      DesiredCapabilities capability = DesiredCapabilities.Chrome();
      capability.SetCapability("key", Environment.GetEnvironmentVariable("TB_KEY"));
      capability.SetCapability("secret", Environment.GetEnvironmentVariable("TB_SECRET"));
      capability.SetCapability("version", "latest-1");
      driver = new RemoteWebDriver(
        new Uri("https://hub.testingbot.com/wd/hub/"), capability
      );
      driver.Navigate().GoToUrl("http://localhost:8080");
      Console.WriteLine(driver.Title);
      driver.Quit();
    }
  }
}

Your test will connect to the local http-server via the TestingBot GitHub Action and print the title of the page.

Inputs

The TestingBot GitHub Action accepts the following inputs:

Input Description
key
Required
Your TestingBot API Key
secret
Required
Your TestingBot API Secret
auth Performs Basic Authentication for specific hosts, only works with HTTP.
debug Enables debug messages. Will output request/response headers.
dns Use a custom DNS server. For example: 8.8.8.8
doctor Perform sanity/health checks to detect possible misconfiguration or problems.
fastFailRegexps Specify domains you don't want to proxy, comma separated.
pac Proxy autoconfiguration. Should be a http(s) URL
sePort The local port your Selenium test should connect to. Default port is 4445
localProxy The port to launch the local proxy on (default 8087).
proxy Specify an upstream proxy: PROXYHOST:PROXYPORT
proxyCredentials Username and password required to access the proxy configured with proxy.
noCache Bypass TestingBot Caching Proxy running on the tunnel VM.
noProxy Do not start a local proxy (requires user provided proxy server on port 8087).
tunnelIdentifier Add an identifier to this tunnel connection.
In case of multiple tunnels, specify this identifier in your desired capabilities to use this specific tunnel.
uploadLogFile Should this action upload the log file generated by the TestingBot Tunnel as an artifact?
Default is true.
retryTimeout How long, in seconds, should the Action wait to retry, if the tunnel fails to start.

Artifacts

The TestingBot GitHub Action will, by default, upload the logfile generated by the TestingBot tunnel.
This allows you to view what happened with the TestingBot Tunnel for each of your Actions.
The logfile is saved as an artifact and can be downloaded.

GitHub Artifact

If you don't want this, you can disable it by setting the input uploadLogFile: "false" in your workflow file.

More Information

More information about this is available on the GitHub Documentation pages and our TestingBot GitHub Action repository.